Bagaimana hasil program ke tempat lain selain STDOUT / STDERR? Bagaimana cara menghindarinya?


15

Ternyata saya tidak tahu semua tujuan keluaran yang tersedia untuk digunakan. Saya tahu tentang stdout( &1) dan stderr( &2). Namun, setelah mengarahkan kedua deskriptor, saya terkadang masih mendapatkan beberapa output di konsol saya!

Contoh termudah yang bisa saya pikirkan adalah GNU Parallel; Setiap kali saya menggunakannya, saya melihat pemberitahuan kutipan. Bahkan ketika saya melakukannya &2>1 > file, saya masih melihat pemberitahuan itu.

Dan hal yang sama berlaku untuk emerge: Ketika saya menjalankan emerge dan ada beberapa masalah, beberapa informasi tidak dicetak stdoutjuga stdin, karena saya mengarahkan mereka dan mereka masih bisa melaluinya.

Saya kebanyakan memecahkan masalah ini dengan menggunakan script, tetapi saya masih bertanya-tanya apa yang menyebabkan masalah ini.


1
Berikan contoh lengkap .
Kusalananda


8
Anda tidak akan mendapatkan semuanya . Sebuah skrip selalu dapat menulis /dev/tty.
Satō Katsura

1
Adapun GNU parallel: mkdir ~/.parallel; touch ~/.parallel/will-citeakan menonaktifkan pesan yang mengganggu. Atau, lihat-lihat untuk implementasi lainnya parallel.
Satō Katsura

2
@OleTange Karena itu bukan masalah - saya bertanya mengapa sesuatu terjadi dan saya gunakan parallelsebagai contoh.
MatthewRock

Jawaban:


40

Sintaks yang Anda gunakan salah.

cmd &2>1 >file

akan dibagi menjadi

cmd &
2>1 >file

Ini akan:

  1. Jalankan cmdsebagai pekerjaan latar belakang tanpa pengalihan
  2. Dalam proses yang terpisah (tanpa perintah!) Akan diarahkan stderrke file yang secara harfiah dipanggil 1dan dialihkan stdoutkefile

Sintaks yang Anda inginkan adalah:

cmd >file 2>&1

Urutan operasi itu penting. Ini akan:

  1. Redirect stdoutkefile
  2. Redirect stderrke &1- yaitu filehandle yang sama denganstdout

Hasilnya adalah keduanya stderrdan stdoutakan dialihkan ke file.

Dalam bash, sintaks non-standar yang lebih sederhana (dan jadi saya tidak merekomendasikannya, berdasarkan portabilitas) cmd &> filemelakukan hal yang sama.


Terima kasih banyak. Masalah lainnya mungkin /dev/tty, tetapi mudah-mudahan ini tidak terjadi terlalu sering (jika sama sekali).
MatthewRock

5
Jika Anda memiliki atperintah di mesin Anda dan memiliki hak untuk menggunakannya, maka Anda dapat menjalankan perintah melalui at now. Lihat halaman manual untuk detailnya. Ini akan menjalankan perintah melalui mekanisme proses batch dan proses tidak akan pernah memiliki tty untuk menulis. Tapi, secara umum, saya tidak akan khawatir tentang kasus tepi ini. Biasanya hanya proses yang membutuhkan interaksi dan sengaja perlu menampilkan sesuatu kepada pengguna meskipun pengalihan akan digunakan /dev/tty.
Stephen Harris

pernah ke sana, melakukan itu
davidbak

10

Ada dua masalah.

Yang pertama adalah bahwa urutan itu penting, yang kedua adalah /dev/tty.

Mari kita gunakan skrip ini sebagai contoh skrip yang ingin kami ambil keluarannya:

test.sh:

#!/bin/bash

echo dada
echo edada 1>&2
echo ttdada >/dev/tty

Sekarang mari kita lihat output dari perintah:

./testmyscript.sh 2>&1 >/dev/null:

edada
ttdada

Karena urutan evaluasi dari kiri ke kanan, pertama-tama kita mendapatkan "redirect stderrke mana pun stdoutkeluaran (jadi, keluaran konsol)". Kemudian kita "dialihkan stdoutke /dev/null. Kita berakhir dengan situasi seperti ini:

stdout-> /dev/null stderr-> konsol

Jadi kami melakukannya dengan benar:

./testmyscript.sh >/dev/null 2>&1

Dan kita mendapatkan:

ttdada.

Sekarang kita melakukan "Redirect stdoutto /dev/null", dan kemudian "Redirect stderr ke tempat stdout menunjuk" (jadi, /dev/null). Hore!

Namun, kami masih memiliki masalah; program dicetak ke /dev/tty. Sekarang saya tidak tahu bagaimana cara memperbaiki perilaku semacam ini, jadi Anda kemungkinan besar akan membutuhkannya script, tetapi semoga perilaku ini tidak terlalu sering terjadi.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.