Fungsi berikut ifnotemptymengirimkan inputnya ke perintah yang diteruskan sebagai argumen, kecuali bahwa ia tidak melakukan apa-apa jika inputnya kosong. Gunakan untuk pipa source --fooke dalam sink --bardengan menulis source --foo | pipe_if_not_empty sink --bar.
Saya berharap implementasi ini bekerja pada semua platform POSIX / Unix, meskipun secara tegas itu tidak sesuai standar: ia bergantung pada ddtidak membaca lebih dari satu byte yang diperintahkan untuk dibaca pada input standarnya.
Saya pikir head -c 1akan menjadi pengganti yang cocok untuk dd bs=1 count=1 2>/dev/nulldi Linux.
Di sisi lain, head -n 1tidak akan cocok karena headbiasanya buffer input dan dapat membaca lebih dari satu baris yang dihasilkan - dan karena itu membaca dari pipa, byte tambahan hilang begitu saja.
read -r headdan bahkan read -r -n 1 headtidak cocok di sini karena jika karakter pertama adalah baris baru, headakan ditetapkan ke string kosong, sehingga tidak mungkin untuk membedakan antara input kosong dan input dimulai dengan baris kosong.
Kita tidak bisa hanya menulis head=$(head -c 1)karena jika karakter pertama adalah baris baru, substitusi perintah akan menghapus baris baru akhir, sehingga tidak mungkin untuk membedakan antara input kosong dan input yang dimulai dengan baris kosong.
Di bash, ksh atau zsh, Anda bisa menggantinya catdengan </dev/stdinuntuk mendapatkan kinerja mikroskopis.
Jika Anda tidak keberatan menyimpan seluruh data antara dalam memori, berikut ini adalah implementasi yang sedikit lebih sederhana pipe_if_not_empty.
Berikut ini adalah implementasi yang sedikit lebih sederhana dengan peringatan berikut:
Data yang dihasilkan oleh sumber dianggap kosong jika dan hanya jika itu hanya terdiri dari karakter baris baru. (Ini sebenarnya mungkin diinginkan.)
Data dimasukkan ke wastafel berakhir dengan tepat satu karakter baris baru, tidak peduli berapa banyak baris baru data yang dihasilkan oleh sumber berakhir. (Ini bisa jadi masalah.)
$ echo -e "\n\n"| xargs -r ls
$ # No output. ls did not run.
$ echo -e "\n\n1"| xargs -r ls
ls: cannot access 1:No such file or directory
Ini sederhana tetapi harus bekerja untuk Anda. Jika "fungsi" Anda mengirim string kosong atau bahkan baris baru ke dalam pipa, xargs -r, akan mencegah lewatnya "fungsi lain".
Fungsi ini gagal untuk saya ketika saya menjalankan echo -en "\nX" | pipe_if_not_empty mail -s "Subject line here" [email protected]. Ia berpikir bahwa linedan herekeduanya adalah penerima email, bukan token dalam subjek. Saya harus melarikan diri dari "sekitar subjek untuk membuatnya bekerja. Namun, pipe_if_not_emptyfungsi dari jawaban yang diterima bekerja untuk saya bahkan tanpa melarikan diri apa pun.
kuzzooroo
2
Setidaknya sesuatu seperti ini berfungsi:
yourcommand | if [ $(wc -c) -gt "0" ]; then yourothercommand; fi
Harap dicatat bahwa di atas akan mempertimbangkan umpan baris dan karakter khusus lainnya sebagai output, sehingga baris kosong diteruskan ke jika pernyataan akan dianggap sebagai output. Cukup naikkan batas -gt jika output Anda biasanya harus lebih tinggi dari 1 byte :)
Jawaban:
Fungsi berikut
ifnotempty
mengirimkan inputnya ke perintah yang diteruskan sebagai argumen, kecuali bahwa ia tidak melakukan apa-apa jika inputnya kosong. Gunakan untuk pipasource --foo
ke dalamsink --bar
dengan menulissource --foo | pipe_if_not_empty sink --bar
.Catatan desain:
dd
tidak membaca lebih dari satu byte yang diperintahkan untuk dibaca pada input standarnya.head -c 1
akan menjadi pengganti yang cocok untukdd bs=1 count=1 2>/dev/null
di Linux.head -n 1
tidak akan cocok karenahead
biasanya buffer input dan dapat membaca lebih dari satu baris yang dihasilkan - dan karena itu membaca dari pipa, byte tambahan hilang begitu saja.read -r head
dan bahkanread -r -n 1 head
tidak cocok di sini karena jika karakter pertama adalah baris baru,head
akan ditetapkan ke string kosong, sehingga tidak mungkin untuk membedakan antara input kosong dan input dimulai dengan baris kosong.head=$(head -c 1)
karena jika karakter pertama adalah baris baru, substitusi perintah akan menghapus baris baru akhir, sehingga tidak mungkin untuk membedakan antara input kosong dan input yang dimulai dengan baris kosong.cat
dengan</dev/stdin
untuk mendapatkan kinerja mikroskopis.Jika Anda tidak keberatan menyimpan seluruh data antara dalam memori, berikut ini adalah implementasi yang sedikit lebih sederhana
pipe_if_not_empty
.Berikut ini adalah implementasi yang sedikit lebih sederhana dengan peringatan berikut:
Sekali lagi, seluruh data disimpan dalam memori.
sumber
Ini seharusnya bekerja untuk Anda
Sebuah contoh
Ini sederhana tetapi harus bekerja untuk Anda. Jika "fungsi" Anda mengirim string kosong atau bahkan baris baru ke dalam pipa, xargs -r, akan mencegah lewatnya "fungsi lain".
Referensi untuk xargs: http://www.oreillynet.com/linux/cmd/cmd.csp?path=x/xargs
sumber
ifne (1) dari moreutils melakukan hal itu. Moreutils tersedia sebagai paket setidaknya di Debian dan Ubuntu, mungkin di distro lain juga.
sumber
Fungsi di bawah ini mencoba untuk membaca byte pertama, dan jika berhasil gema byte itu dan sisanya kucing. Harus efisien dan 100% portabel.
Kasus uji:
sumber
echo -en "\nX" | pipe_if_not_empty mail -s "Subject line here" [email protected]
. Ia berpikir bahwaline
danhere
keduanya adalah penerima email, bukan token dalam subjek. Saya harus melarikan diri dari"
sekitar subjek untuk membuatnya bekerja. Namun,pipe_if_not_empty
fungsi dari jawaban yang diterima bekerja untuk saya bahkan tanpa melarikan diri apa pun.Setidaknya sesuatu seperti ini berfungsi:
yourcommand | if [ $(wc -c) -gt "0" ]; then yourothercommand; fi
Harap dicatat bahwa di atas akan mempertimbangkan umpan baris dan karakter khusus lainnya sebagai output, sehingga baris kosong diteruskan ke jika pernyataan akan dianggap sebagai output. Cukup naikkan batas -gt jika output Anda biasanya harus lebih tinggi dari 1 byte :)
sumber
yourothercommand
tidak pernah melihat output dariyourcommand
.Alih-alih
sender | receiver
:Atau Anda bisa menjadikannya lebih umum dengan mengubahnya untuk menerima program penerima sebagai argumen seperti dalam jawaban Gilles:
sumber