STDERR'e Karşı STDOUT


24

Linux: Komple Referans 6. Baskı ” (sf. 44) 'ya göre, yönlendirme sembollerini kullanarak sadece STDERR' i |&yönlendirebilirsiniz.

Bunu test etmek için oldukça basit bir senaryo yazdım:

#!/bin/bash
echo "Normal Text."
echo "Error Text." >&2

Bu betiği şu şekilde çalıştırıyorum:

./script.sh |& sed 's:^:\t:'

Muhtemelen, sadece STDERR'ye basılan çizgiler girintili olacaktır. Ancak, aslında gördüğüm gibi, bu çalışmıyor:

    Normal Text.
    Error Text. 

Neyi yanlış yapıyorum burada?

Yanıtlar:


26

Kitabınızın hangi metni kullandığını bilmiyorum, ancak bash kılavuzu açıktır (zaten yönlendirmelere biraz aşina iseniz):

Eğer |&kullanılıyorsa, komut1'in standart hatası, standart çıkışına ek olarak, komut2'nin standart girişine boru aracılığıyla bağlanır; için stenodir 2>&1 |. Standart hatanın standart çıktıya dolaysız yönlendirilmesi, komut tarafından belirtilen tüm yönlendirmelerden sonra gerçekleştirilir.

Bu nedenle standart çıktı ile standart hatayı karıştırmak istemiyorsanız, standart çıktıyı başka bir yere yönlendirmeniz gerekir. Bkz. Standart hata akışı (stderr) nasıl greplenir?

{ ./script.sh 2>&1 >&3 | sed 's:^:\t:'; } 3>&1

Hem 1 ve 3. fd script.shve sedancak orijinal stdout'u hedefe işaret edecektir. İyi bir vatandaş olmak istiyorsanız, bu komutların gerekmediği fd 3'ü kapatabilirsiniz:

{ ./script.sh 2>&1 >&3 3>&- | sed 's:^:\t:' 3>&-; } 3>&1

bashve - (fd hareketi) 'yi ksh93yoğunlaştırabilir .>&3 3>&->&3-


Beşinci el kitabı bana tamamen açık değil. Tavsiyen gibi Oldukça neden anlamıyorum ./script.sh > /tmp/stdout_goes_here |& grep 'grepping_script_stderr'işi değil amaçlandığı gibi, yani: yönlendirme script.sh'ın stdout(ilk gerçekleşmesi gereken manuel pasajı göre olan), daha sonra izin grepkomut en işlemek için stderr. Bunun yerine, stderrve tdout` ikisi de sona stdout_goes_here
eriyor

1
@ sxc731 |&için shorthard edilir 2>&1 |. Yani >/tmp/stdout_goes_here |&yönlendirmeleri için stdout'a /tmp/stdout_goes_hereardından 2>&1stdout'u olan gidiyor her yerde stderr yönlendirir /tmp/stdout_goes_herenihayet, ve |komutun çıktısı yönlendirildi çünkü herhangi bir giriş almaz. Dosya tanıtıcısı 1'in nereye gideceğini değil, dosya tanıtıcısı 1'in biteceği yere>&1 yönlendirmeyeceğinizi unutmayın . Stderr komutunu kullanmak ve stdout dosyasını bir dosyaya yönlendirmek için tek yoldur . 2>&1 >/tmp/stdout_goes_here |
Gilles 'SO- kötü olmayı bırak'

6

|&stderr'i stdin'e dönüştürür 2>&1 |, yani, bir sonraki program her ikisini de stdin'de alır.

$cat test.sh
#!/bin/bash
echo "Normal Text."
echo "Error Text." >&2
$./test.sh | sed 's:^:\t:'
Error Text.
        Normal Text.
$ ./test.sh |& sed 's:^:\t:'
        Normal Text.
        Error Text.

Demek temel olarak daha uzun ifadeye denk runcommand 2>&1 | tee? yani runcommand |& tee?
Naftuli Kay

evet, onlar aynı.
Kevin

1

|&bash için sadece (çok taşınabilir olmayan) bir kısayol var 2>&1 |, bu yüzden girintili her çizgiyi görmelisiniz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.