Cara menjalankan perintah di latar belakang tanpa output kecuali ada kesalahan

14

Bagaimana cara menekan output perintah tetapi menunjukkannya jika perintah keluar kode kesalahan?

Xster
sumber

Jawaban:

17

Sayangnya, asumsi yang stderrhanya digunakan untuk output kesalahan tidak selalu benar. Sebaliknya, stderrsering digunakan untuk setiap dan semua output interaktif dan diagnostik, yaitu output yang ditujukan bagi pengguna untuk membaca dalam prompt interaktif 1 . wgetdan ddmerupakan contoh yang terkenal.

Beberapa perintah akan memberikan flag (misalnya -quietatau -silent) untuk menekan output non-error - baca halaman manual mereka untuk melihat apakah ada.


Konvensi lain yang lebih sering digunakan adalah kode keluar : program mengembalikan kode keluar saat keluar. Biasanya 2 , kode keluar 0menunjukkan keberhasilan, dan kode keluar lainnya menunjukkan kesalahan.

Dengan bash, Anda bisa mendapatkan kode keluar dari perintah terakhir dari $?variabel. Di fish, gunakan $statusvariabel. Anda dapat mem-pipe stderrke file sementara dan hanya mencetaknya jika terjadi kesalahan. Misalnya ( fish):

command 2>/tmp/outputbuffer
if $status
    cat /tmp/outputbuffer
rm /tmp/outputbuffer

Anda juga dapat menggunakan beberapa pintasan, jika Anda tidak merantai perintah:

if command 2>/tmp/outputbuffer
    cat /tmp/outputbuffer
rm /tmp/outputbuffer

Atau:

command 2>/tmp/outputbuffer; or cat /tmp/outputbuffer; rm /tmp/outputbuffer;

Anda juga stdoutdapat mengirim pipa ke buffer yang sama dengan menggunakan 2>&1 >/tmp/outputbuffer.

(Catatan: Saya tidak benar-benar tahu fish, jadi saya mengadaptasi konsep untuk apa yang dapat saya temukan dalam dokumentasinya. Sintaksnya mungkin sedikit salah. Juga, Anda dapat menggunakan mktempuntuk menghasilkan file sementara yang unik - jalankan dan catat nama file dalam variabel.)

Jika Anda perlu menjalankan semuanya di latar belakang shell yang juga Anda gunakan secara interaktif pada saat yang sama, maka Anda lebih baik menulis skrip untuk menangani keluaran-bersembunyi dan menjalankan skrip di latar belakang dengan teknik standar ( fish). Heck, Anda dapat memasukkan sesuatu seperti fungsi berikut di ~/.config/fish/config.fish:

function run-silent
    set temp (mktemp)
    if $argv 2>&1 >$temp
        cat $temp
    rm $temp
end

Panggil dengan run-silent somecommand &(di mana jejak &menyebabkannya berjalan di latar belakang)

Perhatikan bahwa ini akan menelan kode keluar asli, dan akan membuang keduanya stdoutdan stderrjika terjadi kegagalan. Anda dapat menyesuaikannya sesuai kebutuhan.


1 Bahkan tidak ada jaminan bahwa output kesalahan tidak akan muncul stdout- beberapa program akan membuang semua output di sana!

2 Sayangnya, ini masih tidak selalu terjadi - kode keluar sepenuhnya dikendalikan oleh program, dan beberapa akan menunjukkan beberapa kondisi keberhasilan dengan keluar tidak nol. Sekali lagi, periksa manualnya.

Bob
sumber
sedikit tweak ikan, ada tempat khusus untuk meletakkan fungsi di ~ / .config / fish / functions /
Xster
12

Utilitas Unix mengirim pesan umum ke stdout, dan pesan kesalahan stderr, jadi jika kita hanya ingin melihat pesan kesalahan, maka itu akan cukup untuk menekan stdoutsehingga hanya stderrmendapatkan output ke konsol.

Cara untuk melakukan ini (dalam keduanya bashdan fish) adalah dengan menambahkan >/dev/nullperintah. Pipa ini stdout ke ketiadaan, tetapi stderr (dengan pesan kesalahan Anda) masih masuk ke konsol.

Jadi misalnya:

Perintah echo 1 >/dev/nulltidak mencetak apa pun, karena stdoutoutput normal ditekan, dan tidak ada yang ditulis untuk stderr.

Perintah man doesnotexist >/dev/nullmencetak pesan kesalahan, karena manmenulis pesan kesalahannya ke stderr.

Maximillian Laumeister
sumber
2

Ini akan menjalankan perintah di latar belakang dan menulis kesalahan ke file log ketika mengabaikan keluaran normal

    command > /dev/null 2> /tmp/example_error.log &
Genkus
sumber