bash betiğinde stderr mesajlarını bastır


48

Aşağıdaki (biraz aptalca) komut dosyası adını 'test1.sh' düşünün:

#/bin/bash
#
sleep 10 &
echo sleep pid = $!
pkill sleep

Çalıştırdığımda, yalnızca yankı çıktısını almakla kalmıyor, aynı zamanda bash'ın stderr'deki uykunun ölümünü bildirdiğini görüyorum:

$ ./test1.sh
sleep pid = 3551
./test1.sh: line 5:  3551 Terminated              sleep 10

Bu durumda, çıktının stderr'e bastırılmasını isterim. Komut satırında yapabildiğimi biliyorum:

$ ./test1.sh 2> /dev/null

... ama onu bastırmak için bir yol var içinde komut dosyası? (İkinci bir betiğe sarabileceğimi ve sargının yönlendirmesini sağlayabileceğimi biliyorum, ancak daha kolay bir şey olmalı ...)


pkill uykusundan sonra yönlendirme 2> / dev / null komutunu eklemeye çalıştınız mı?
rahul

@ rahul: evet yaptım - pkill mesajı üretmiyor, bash.
fearless_fool

Pkill yerine kill kullandım ve stderr alamadım. garip ..
rahul

@rahul: yerleşik olmayan bir şey içinde yerleşik bir olabilir mi? Bunu pkill ile de denedin mi?
fearless_fool

evet, inanıyorum. Pkill ile aynı hatayı alıyorum ama öldürme ile değil. Kill kullanırken, proc adı yerine pid kullandım.
rahul

Yanıtlar:


72

Haklısın; pkill mesajı üretmiyor, bash. Bunu önerirsin

$ ./test1.sh 2> /dev/null

olası bir çözümdür. UVV'nin işaret ettiği gibi, betiğin içindeki eşdeğer eylem

exec 2> /dev/null

Bu, betiğin stderr'ini /dev/null geri dönene kadar bu ifadeden yönlendirir . Geri değiştirmenin sakar yolları

exec 2> /dev/tty

stderr'i terminale yönlendirir. Bu muhtemelen başlangıçta olduğu (ancak ille de değil) olduğu yer.

Veya

exec 2>&1

hangi stderr'yi stdout ile aynı olacak şekilde ayarlar ve yanlış olması muhtemeldir.

Daha güvenilir bir yol

exec 3> & 2
exec 2> / dev / null
(stderr'i görmek istemediğiniz şeyleri yapın.) 
exec 2> & 3

Bu, orijinal stderr'i dosya tanımlayıcı 3'e kaydeder ve daha sonra geri yükler.

Sadece süreç ölümünün açıklanmasını bastırmanın diğer yolları:

(sleep 10 & pkill sleep) 2> /dev/null

ve

{ sleep 10 & pkill sleep;} 2> /dev/null

stderr'i sadece gruplandırılmış komutlar için değiştirir.


Bu harika, ayrıntılı bir cevap. Teşekkürler bayım!
Keenan Lawrence,

Orijinal tanımlayıcıları göndererek ve daha sonra geri yükleyerek kaydetme stdinve stderryeni dosya tanımlayıcılarla ilgili herhangi bir tehlike var /dev/nullmı?
Alexej Magura

Eh, sanırım, eğer (sizin bilmediğiniz) dosya tanımlayıcı 3'e (veya 4) yazmış bir program çalıştırırsanız, bu işlem normal şartlarda başarısız olur. Ancak, program başarısızlığı görmezden gelmek ve rapor etmeden devam etmek için yazılabilir; o zaman asla bilemezsin. Ancak, dosya tanımlayıcınız 1 (veya 2), dosya tanımlayıcınız 3 (veya 4) üzerinde "park edilmiş" olsaydı, o zaman bu program aniden betiğinizin stdout'una ya da stderr'ine yazardı. Ama bu çok tartışmalı bir örnek ve yine de asgari tehlike. Aklında bir şey mi var?
Scott

1
Şimdi, Scott'ın gruplandırılmış komuta yaklaşımını tercih ediyorum, yani{ sleep 10 & pkill sleep;} 2> /dev/null
fearless_fool

9

Göre bu aşağıdaki gibi bir şey yapabilirsiniz:

#!/bin/bash
exec 2>/dev/null
ls -al test
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.