Stdout ve stderr'i bir dosyaya nasıl yönlendirebilir ve stderr'ı konsola nasıl görüntüleyebilirim?


18

Nasıl bir dosyaya yönlendirme ve tee kullanmak biliyorum; temel düzeyde. Yani

$ alias outanderr='bash -c "echo stdout >&1; echo stderr >&2"'
# A fake "application" displaying both output and error messages.

$ outanderr 1>file      # redirect stdout to a file, display stderr
stderr

$ outanderr 2>file      # redirect stderr to a file, display stdout
stdout

$ outanderr 1>file 2>&1 # redirect both to a file, display nothing

$ outanderr | tee file; echo "-- file contents --" && cat file
# redirect stdout to a file, display both (note: order is messed up)
stderr
stdout
-- file contents --
stdout

$ outanderr 2>&1 | tee file; echo "-- file contents --" && cat file
# redirect both to a file, display both
stdout
stderr
-- file contents --
stdout
stderr

Soru şudur: Aşağıdaki çıktıyı almak için soru işaretlerinin yerine ne yazılır:

$ outanderr ???; echo "-- file contents --" && cat file
# redirect both to a file, display stderr
stderr
-- file contents --
stdout
stderr

Constaints:

  • Bash varsayalım.
  • Sipariş dosyada tutulmalıdır.
  • stderr içeriği gerçek zamanlı olarak satır satır görüntülenir, yani arabellek yok.
  • Ayrı komut dosyaları kullanılabilir.
  • Büyü gerekli olabilir.

outanderrProgramın kontrolü ne kadar ?
Kevin

1
@Kevin Bence soru bundan daha genel. Burada, outanderrstdout'a bir satır ve stderr'a başka bir satır yazdıran bir takma ad var. Fikir (mümkünse), herhangi bir programda değişiklik yapmadan çalışabilecek genel bir çözüm oluşturmaktır.
lgeorget

@lgeorget Bunu anlıyorum, ancak genel bir çözümdeki tüm kısıtlamaları kesinlikle yerine getirmenin mümkün olduğuna inanmıyorum, bu yüzden belirli bir çözüm elde edip edemeyeceğimizi görüyordum.
Kevin

@Igeorget haklı.
TWiStErRob

Yanıtlar:


12
2>&1 >>outputfile | tee --append outputfile

Kolay test için:

echo -n >outputfile; bash -c "echo stdout >&1; echo stderr >&2" 2>&1 >>outputfile |
  tee --append outputfile; echo "outputfile:"; cat outputfile

Düzenleme 1:

Bu dosyaya stdout (yalnızca) yazarak, borudan geçecek şekilde sterr stdout yaparak ve çıktısını aynı dosyaya yazarak çalışır.

Her iki yazma da ekleme modunda ( >>yerine >) yapılmalıdır, aksi takdirde her ikisi de birbirlerinin çıktılarının üzerine yazar.

Boru bir tampon olduğundan, çıktının dosyada doğru sırada görüneceğine dair bir garanti yoktur. Bir uygulama her iki dosya tanımlayıcısına (iki kanal) bağlıysa bile değişmez. Garantili sipariş için her iki çıkışın da aynı kanaldan geçmesi ve sırasıyla işaretlenmesi gerekir. Ya da gerçekten süslü şeylere ihtiyacınız olacak:

  1. Hem stdout hem de stderr bir dosyaya (aynı dosyaya değil!) Yönlendirildiyse ve her iki dosya da FUSE birimindeyse, FUSE modülü her bir yazımı bir zaman damgasıyla işaretleyebilir, böylece ikinci bir uygulama verileri doğru bir şekilde sıralayabilir ve birleştirebilir gerçek çıktı dosyası için. Veya verileri işaretlemezsiniz, ancak modülün birleştirilmiş çıktı dosyasını oluşturmasını istersiniz. Muhtemelen henüz bir FUSE modülü yok ...
  2. Hem stdout hem de stderr yönlendirilebilir /dev/null. Uygulamanın çıktıları çalıştırılarak birbirinden ayrılacaktır strace -f -s 32000 -e trace=write. Bu durumda kaçmayı tersine çevirmeniz gerekir. Uygulamanın izlenerek daha hızlı çalışmadığını söylemeye gerek yok.
  3. Belki de mevcut, basit bir FUSE modülü kullanılarak ve uygulama yerine modülün izlenmesi ile bu hedefe ulaşılabilir. Modül muhtemelen uygulamadan çok daha az sistem çağrısına sahip olduğundan (veya daha doğrusu: if) uygulamayı izlemekten daha hızlı olabilir.
  4. Uygulamanın kendisi değiştirilebilirse: Uygulama her çıkıştan sonra durdurulabilir (ancak bunun sadece içeriden mümkün olduğunu düşünüyorum) ve sadece s sinyalini aldıktan sonra devam edebilir (SIGUSR1 veya SIGCONT). Borudan okunan uygulamanın, hem boruda hem de dosyada yeni veri olup olmadığını kontrol etmesi ve her yeni veriden sonra sinyali göndermesi gerekir. Uygulama türüne bağlı olarak, strace yönteminden daha hızlı veya daha yavaş olabilir. SİGORTA maksimum hız çözümü olacaktır.

1
Bah. Beni tam olarak aynı cevabı yazmanın ortasında yakala neden yapmıyorsun.
Kevin

2
Not: Bu, / err hatlarını değiştirme olasılığını tanıtan bir yarış durumu var, ancak bunun önlenebileceğini düşünmüyorum.
Kevin

1
@Kevin Bu en iyimizin başına gelir, daha önce acı çektim ve neredeyse "birisinin yazdığını göster" özelliğini (bu da karmaşık olurdu) istemiştim. Bana öyle geliyor ki, yarış durumu sadece dosyaya bir yazma işlemi (stdout) boru hattına yazıldıktan sonra gerçekleşirse ortaya çıkar.
Hauke ​​Laging

Değil gönderme de o misiniz stdoutve stderrkarşı teeveya bir şey eksik? Bence OP'nin gerekliliği tee stderrsadece.
Joseph R.

@JosephR. Bunu denemedin mi?
Hauke ​​Laging
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.