Katakanlah saya sudah mendapat saluran pipa berikut:
cmd1 < input.txt |\
cmd2 |\
cmd4 |\
cmd5 |\
cmd6 |\
(...) |\
cmdN > result.txt
Dalam kondisi tertentu saya ingin menambahkan cmd3
antara cmd2
dan cmd4
. Apakah ada cara untuk membuat semacam pipa kondisional tanpa menyimpan hasil cmd2 ke dalam file sementara? Saya akan memikirkan sesuatu seperti:
cmd1 < input.txt |\
cmd2 |\
(${DEFINED}? cmd3 : cat ) |\
cmd4 |\
cmd5 |\
cmd6 |\
(...) |\
cmdN > result.txt
Jawaban:
Seperti biasa
&&
dan||
operator:(Perhatikan bahwa tidak ada garis miring terbalik yang diperlukan saat garis berakhir dengan pipa.)
Perbarui menurut pengamatan Jonas .
Jika cmd3 dapat diakhiri dengan kode keluar bukan nol dan Anda tidak ingin
cat
memproses input yang tersisa, balikkan logika:sumber
cat
kembali dengan status keluar non-nol (umum ketika mendapatkan SIGPIPE), makacmd3
akan dijalankan. Lebih baik gunakan if / then / else seperti pada jawaban Thor atau solusi lain yang tidak berjalancat
.if
/else
/fi
bekerja. Dengan asumsi shell seperti Bourne:sumber
Semua jawaban yang diberikan sejauh ini diganti
cmd3
dengancat
. Anda juga dapat menghindari menjalankan perintah apa pun dengan:Itu POSIX, tetapi perhatikan bahwa jika dalam
bash
skripbash
yang tidak dalamsh
-mode (seperti skrip yang dimulai dengan#! /path/to/bash
), Anda harus mengaktifkan alias ekspansi denganshopt -s expand_aliases
(atauset -o posix
).Pendekatan lain yang masih tidak menjalankan perintah yang tidak perlu adalah menggunakan eval:
Atau:
Di Linux (setidaknya), alih-alih
cat
, Anda bisa menggunakanpv -q
yang menggunakansplice()
alih-alihread()
+write()
untuk melewatkan data di antara dua pipa yang menghindari data dipindahkan dua kali antara ruang kernel dan pengguna.sumber
Sebagai tambahan untuk jawaban manatwork yang diterima : waspadai dan-false-atau gotcha dan interaksinya dengan stream. Contohnya,
output
foo
. Tidak mengherankan,dan
keduanya output
baz
. (Catatan yangecho foo | grep bar
salah dan tidak memiliki output). Namun,tidak menghasilkan apa-apa. Ini mungkin atau mungkin bukan yang Anda inginkan.
sumber
else
(atau||
) harus bertindak sebagai operasi nol menjaga input tidak berubah. Jadi, ganticat
denganecho
perubahan, semuanya membuat kode Anda tidak relevan. Mengenai "dan-false-or gotcha", saya tidak melihat adanya gangguan dengan pipeline: pastebin.com/u6Jq0bZe[[ "${DEFINED}" ]] && cmd3 || cat
,cmd3
dancat
bukan merupakan cabang yang sama-sama eksklusifthen
danelse
samaif
, tetapi jikacmd3
gagal, makacat
juga akan dieksekusi. (Tentu saja, jikacmd3
selalu berhasil, atau jika mengkonsumsi semua input sehingga tidak ada yang tersisastdin
untukcat
diproses, maka itu mungkin tidak masalah.) Jika Anda membutuhkan keduanyathen
danelse
cabang, lebih baik menggunakanif
perintah eksplisit , bukan&&
dan||
.Saya memiliki situasi serupa yang saya selesaikan dengan fungsi bash :
sumber
Berikut ini adalah alternatif solusi yang mungkin:
menggabungkan pipa bernama untuk membuat pseudo-pipeline:
sumber
Untuk referensi di masa mendatang, jika Anda datang ke sini mencari pipa bersyarat pada ikan , ini adalah bagaimana Anda melakukannya:
sumber