Neden bazı Linux programlarının çıktısı STDOUT ya da STDERR'a gitmiyor?


21

Neden bazı Linux programlarının çıktısı STDOUT ya da STDERR'a gitmiyor?

Aslında, hangi “akışı” kullanırsa kullansın, tüm program çıktılarını nasıl güvenilir bir şekilde yakalayacağımı bilmek istiyorum. Sahip olduğum sorun, bazı programların çıktılarının yakalanmasına izin vermiyor gibi görünmesi.

Bir örnek 'time' komutu:

time sleep 1 2>&1 > /dev/null

real        0m1.003s
user        0m0.000s
sys         0m0.000s

veya

time sleep 1 &> /dev/null

real        0m1.003s
user        0m0.000s
sys         0m0.000s

Neden çıktıyı iki kere görüyorum? Her şeyin / dev / null'a aktarılmasını bekledim .

Hangi çıkış akımı zaman kullanıyor ve onu bir dosyaya nasıl aktarabilirim?

Bu sorunu çözmenin bir yolu , örneğin combine.shbu komutu içeren bir Bash betiği oluşturmaktır :

$@ 2>&1

Daha sonra 'zaman' çıktısı doğru şekilde yakalanabilir:

combine.sh time sleep 1 &> /dev/null

(çıktı yok - doğru)

Ayrı bir birleştirme komut dosyası kullanmadan istediğimi elde etmek için bir yolu var mı?


3
İlk Sırayı tersine olmalıdır: 2>&1 > /dev/null2 şimdi (varsayılan olarak, yani terminali) 1 gittiği yere gider" demektir ve ardından 1 şimdi gider için / dev / null (ancak 2 hala terminali gider!) kullanın. >/dev/null 2>&1söylemek Msgstr "" 1 şimdi / dev / null 'a gider, sonra 2 1' in olduğu yere (yani / dev / null 'a) gider. Yerleşik 'zaman' yönlendirilmeyeceği için bu hala burada çalışmayacak, ancak daha genel olarak doğru (örneğin, / usr / bin / time kullanırsanız işe yarar). 1 gidiş 2 içine 1'ler "yönünü" kopyalama, değil 2 olarak düşünün "2> & 1"
Olivier Dulac

Yanıtlar:


38

Bu soru BashFAQ / 032'de ele alınmıştır . Örnekte şunları yaparsınız:

{ time sleep 1; } 2> /dev/null

Nedeni neden

time sleep 1 2>/dev/null

O sözdizimi, sen isteyeceksiniz çünkü nasıl bekliyorsanız davranmaz timekomuta sleep 1 2>/dev/null(evet, komut sleep 1ile stderr'e yönlendirildi /dev/null). Yerleşik timebunu gerçekten mümkün kılmak için bu şekilde çalışır.

bash Yerleşik iyi, bir yerleşik çünkü ... aslında bunu yapabilirsiniz. Böyle bir davranış timegenellikle içinde bulunan harici komutla imkansız olur /usr/bin. Aslında:

$ /usr/bin/time sleep 1 2>/dev/null
$

Şimdi, sorunuzun cevabı

Neden bazı linux programlarının çıktısı STDOUT veya STDERR'a gitmiyor?

is: yapar, çıktı stdout'a veya stderr'ye gider .

Bu yardımcı olur umarım!


2
siz açık bir şekilde olanlara gidip diğer fd oluşturabilir ve komutları olabilir (örn: bash komut: exec 3>/some/file ; ls >&3 ;)
Olivier Dulac

@OlivierDulac Yerleşik ile emin veya hatta daha basit coproc. Ancak timeyerleşik için durum böyle değil .
gniourf_gniourf

@ gniourf-gniourf: "Çıktı stdout veya stderr'a gidiyor" cümleniz nedeniyle yorum yapıyordum ^^ ^^
Olivier Dulac

14

Hakkında belirli soru timeyerleşiğini cevap olmuştur, ama orada vardır ya yazmıyorum bazı komutlar stdoutveya stderr. Klasik bir örnek Unix komutudur crypt. cryptargüman olmadan standart girdiyi şifreler stdinve standart çıktıya yazar stdout. Kullanıcıyı getpass(), varsayılan olarak bir komut istemi çıkaran kullanan bir şifre ister /dev/tty. /dev/ttyGeçerli terminal cihazıdır. Yazma /dev/tty, mevcut terminale yazma etkisine sahiptir (eğer varsa isatty()).

Bunun sebebi cryptyazamadığı için stdoutşifreli çıktı yazmasıdır stdout. Ayrıca, bir kullanıcı yönlendirir ve istemde hala görülmesi için, /dev/ttyyerine yazmak isteyip istemediğiniz sorulur. (Aynı nedenle, şifrelenecek verileri okumak için kullanıldığından şifreyi okuyamaz.)stderrstdoutstderrcryptstdin


2
+1. OP için daha az ilgi çekici, ancak karşı karşıya gelen herkes için daha uygun "Neden bazı linux programlarının çıktısı STDOUT veya STDERR'ye gitmiyor?" Google üzerinden. :-)
ruakh

0

time sleep 1 > /dev/null 2>&1# yönlendirir "sleep's" çıkışı boş. Ardından, "zaman", yeniden yönlendirme olmadan kendi çıktısını yazar. " time (sleep 1 > /dev/null 2>&1)" Gibi .

(time sleep 1) > /dev/null 2>&1 # "zaman uykusu 1" i çalıştırır, ardından çıktısını null değerine yönlendirir.

[] S


-1

Sizin durumunuzdaki sorun, yeniden yönlendirmenin başka bir şekilde çalışmasıdır. Sen yazdın

time sleep 1 2>&1 > /dev/null

Bu standart çıktıyı /dev/nullyönlendirir ve sonra standart hatayı standart çıktıya yönlendirir.

Tüm çıktıları yönlendirmek için yazmak zorundasınız.

time sleep 1 > /dev/null 2>&1 

Ardından standart hata standart çıkışa yönlendirilir ve bundan sonra tüm standart çıkışlara (standart hata içeren) yönlendirilir /dev/null.


Bu bash yerleşiği ile çalışmıyor time. Bazı açıklamalar için cevabımı gör.
gniourf_gniourf

+1, çünkü bu benzer bir soruya faydalı bir cevap. Her ne kadar @Olivier, yukarıdaki soruya yorumda daha iyi açıklar.
Will Sheppard
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.