stderr'i bir dosyaya nasıl yönlendirilir [çoğaltılır]

157

Nohup'u arka planda çalıştırılacak bir komut koymak için kullanırken, içeriğin bir kısmı terminalde görünür.

cp: error reading ‘/mnt/tt/file.txt’: Input/output error
cp: failed to extend ‘/mnt/tt/file.txt’: Input/output error

Bu içeriği bir dosyaya kaydetmek istiyorum.

    
sordu André M. Faria 18.05.2015 14:31

2 cevap

258

Linux'ta (ve diğer işletim sistemlerinde) iki ana çıkış akımı, standart çıktı (stdout) ve standart hata (stderr) vardır. Gösterdiğiniz gibi hata mesajları standart hataya yazdırılır. Klasik yönlendirme operatörü ( command > file ) sadece standart çıkışı yönlendirir, bu nedenle terminalde standart hata hala gösterilir. Stderr'i de yönlendirmek için birkaç seçeneğiniz var:

  1. Stdout'u bir dosyaya yönlendirin ve başka bir dosyaya stderr:

    command > out 2>error
    
  2. Stderr'i stdout'a ( &1 ) yönlendirin ve sonra stdout'u bir dosyaya yönlendirin:

    command >out 2>&1
    
  3. Her ikisini de bir dosyaya yönlendirin:

    command &> out
    

Çeşitli kontrol ve yönlendirme operatörleri hakkında daha fazla bilgi için bkz. buradaki .

    
verilen cevap terdon 18.05.2015 14:50
4

Unutulmaması gereken ilk şey, amacınıza ve kabuğunuza bağlı olarak birkaç yolun bulunmasıdır, bu nedenle bu, birden çok yönün anlaşılmasını gerektirir. Çoğu, Bourne benzeri kabuklarda % co_de yoluyladır, örneğin 2> ( dash ile simgelenir) ve /bin/sh ; Birincisi, varsayılan ve POSIX uyumlu kabuk ve diğeri ise çoğu kullanıcının etkileşimli oturum için kullandığı şeydir. Sözdizimi ve özellikleri farklıdır, ancak neyse ki bizim için hata akışı yeniden yönlendirme aynı şekilde çalışır ( bash standart olmayanı hariç). Csh ve onun türevleri durumunda, stderr yönlendirmesi pek işe yaramıyor.

Haydi &> bölümüne geri dönelim. Dikkat edilmesi gereken iki önemli nokta: 2> , bir dosyayı açtığımız ve > tamsayı, stderr dosya tanıtıcısı anlamına gelen yönlendirme operatörü anlamına gelir; gerçekte bu, kabuk dili için POSIX standardının bölüm 2.7 şeklinde yeniden yönlendirmeyi nasıl tanımladığıdır:

[n]redir-op word

Basit 2 yönlendirme için > tamsayı 1 için, yani stdout 'si echo Hello World > /dev/null ile aynıdır. Tamsayı veya yönlendirme operatörünün alıntılanamayacağını unutmayın, aksi halde kabuk onları böyle algılamaz ve bunun yerine metinlerin tam metin dizesi olarak kabul edilir. Aralıklamada, tamsayı'nın yönlendirme operatörünün hemen yanında olması önemlidir, ancak dosya yeniden yönlendirme operatörünün yanında olabilir ya da olmayabilir, yani echo Hello World 1>/dev/null ve command 2>/dev/null öğesi iyi çalışır.

Kabuğundaki tipik komut için biraz basitleştirilmiş sözdizimi şöyle olurdu

 command [arg1] [arg2]  2> /dev/null

Buradaki hile, yönlendirme her yerde görünebilir. Bu hem command 2> /dev/null hem de 2> command [arg1] geçerlidir. % Co_de% kabuğu için, hem stdout hem de stderr akışlarını aynı anda yeniden yönlendirmek için command 2> [arg1] yolunun bulunduğunu unutmayın, ancak yine - bu özel bir şeydir ve komut dosyalarının taşınabilirliği için çalışıyorsanız, işe yaramayabilir. Ayrıca bkz. Ubuntu Wiki ve & amp; & gt; ve 2 & 1 & 1 .

Not: bash yönlendirme operatörü bir dosya varsa keser ve eğer varsa dosya üzerine yazar. % Co_de%, &> dosyasının dosyaya eklenmesi için kullanılabilir.

Fark ederseniz, > tek bir komut içindir. Komut dosyaları için, tüm komut dosyasının stderr akışını 2>> olarak dışardan yönlendirebiliriz veya yerleşik yerleşik <; / a>. Yerleşik exec, tüm kabuk oturumu için akışı yeniden yazma gücüne sahiptir, bu yüzden ister etkileşimli isterse komut dosyasıyla olsun, konuşmak için.

gibi bir şey
#!/bin/sh
exec 2> ./my_log_file.txt
stat /etc/non_existing_file

Bu örnekte, günlük dosyası stderr değerini göstermelidir.

Yine başka bir şekilde işlevler aracılığıyla. kopciuszek cevabında belirttiği gibi, zaten iliştirilmiş yönlendirmeyle işlev bildirimi yazabiliriz, yani

some_function(){
    command1
    command2
} 2> my_log_file.txt
    
verilen cevap Sergiy Kolodyazhnyy 03.05.2018 09:48

Etiketlerdeki diğer soruları oku