2013-03-14 14 views
6

Perl'in sadece STDOUT aynı değilse STDERR'ye yazmasını istiyorum. Örneğin, hem STDOUT hem STDERR çıkışı Terminal'e yönlendirirse, STDERR'in yazdırılmasını istemiyorum. Ben dışarı yönlendirirseniz, AncakSTDER, yalnızca farklı bir hedefse STDERR'ye nasıl yazdırılır?

bash $ outerr.pl 
Hello standard output! 

:

#!/usr/bin/perl 

use strict; 
use warnings; 

print STDOUT "Hello standard output!\n"; 
print STDERR "Hello standard error\n" if ($someMagicalFlag); 
exit 0 

Şimdi (bu ben başarmak istiyorum budur) bu göz önünde bulundurun:

şu örneği (outerr.pl) düşünün tersi

bash $ outerr.pl > /dev/null 
Hello standard error 

ve similary:: dosya, ben almak istiyorum

Dışarı hem doğrudan ediyorsanız
bash $ outerr.pl 2> /dev/null 
Hello standard output! 

/aynı dosyaya err, daha sonra sadece dışarı görüntülenmesi gereken:

bash $ outerr.pl > foo.txt 2>&1 
bash $ cat foo.txt 
Hello standard output! 

Yani OUT belirlemek ve ERR/değerlendirmek için bir yol var ve aynı “şey” e işaret ediyor (açıklayıcı?)? o bir terminal ise

-t STDERR 

gerçek olacak ve aynı şekilde STDOUT için:

+0

STDERR ve STDOUT öğelerinin 1 ve 2 gibi kendi tanımlayıcıları vardır. Her ikisi de genellikle konsola yazdırır. – squiguy

+2

Gerçekten yapman gerekenin bir adım geri çekilmesi ve bunu istemenin nedenlerini tekrar gözden geçirmesi gerektiğinden şüpheleniyorum. Gerçek amacınızı gerçekleştirmenin daha iyi bir yolu var, her ne olursa olsun. –

+0

Ilmari Karonen ile birlikteyim. Bunun için neden endişeleneceğini gerçekten anlayamıyorum. Mesajları kopyalamak için olmamalı. STDOUT ve STDERR doğal olarak farklı olmalıdır. Nominal mesajlar STDOUT'a gider ve hata veya uyarı mesajları STDERR'e gider. Asla kucağından geçmeli. – titanofold

cevap

5

yapmanız gerekir:

my @stat_err = stat STDERR; 
my @stat_out = stat STDOUT; 

my $stderr_is_not_stdout = (($stat_err[0] != $stat_out[0]) || 
          ($stat_err[1] != $stat_out[1])); 

Ama gerçek inode'a yok Windows üzerinde çalışmaz. Hem yanlış pozitifler (olmadıklarında farklı olduklarını düşünür) hem de yanlış negatifler (olmadıklarında aynı olduklarını düşünür) verir.

+0

Bu kesinlikle benim yapacağım şeydi. – tchrist

+0

+1 işaret etmek için taşınabilir değildir ve hala bilinmesi yararlıdır. –

+0

Teşekkür ederim @cjm. Bu * Tam olarak ne * arıyorum. ... Windows nedir btw? ;-) –

4

Bunu (neredeyse) -t ile yapabilirsiniz.

Bu hala size hangi terminali söylemeyecek ve aynı dosyaya yeniden yönlendirirseniz, her ikisini de elde edebilirsiniz.

-t STDERR && ! (-t STDOUT) || -t STDOUT && !(-t STDERR) 

veya daha kısa

-t STDOUT^-t STDERR # thanks to @mob 

biliyorsanız

Dolayısıyla, iyisin.

DÜZENLEME: STDERR ve STDOUT hem normal dosyalardır durum için Çözümler:

Tom Christianson Stat ve dev ve alanlar ino karşılaştırmak önerdi. Bu, UNIX'te çalışacak, ancak, Windows'da değil, cjm'nin işaret ettiği gibi.

başka hiçbir programın dosyasına yazacak garanti edemez ise, yapabileceği aşağıdaki hem Windows ve UNIX:

  1. onay STDOUT ve STDERR için dosya tanımlayıcıları altındadır pozisyon, eğer eşit değiller, bunlardan birini >> ile bir muaf olmayan dosyaya yeniden yönlendirdiniz.
  2. Aksi takdirde, dosya tanımlayıcısına 42 bayt yazınız 2
  3. Dosya tanıtıcısının 1 sonuna kadar arama yapın. Daha önce 42'den fazla ise, her ikisi de aynı dosyaya yeniden yönlendirilmiş olma olasılığı yüksektir. Eğer değişmezse, dosyalar farklıdır. Eğer değiştirilir, ancak 42 ile değil, başka biri orada yazıyor, tüm bahisler kapalı (ama sonra Windows'da değilsiniz, böylece stat yöntemi çalışacaktır).
  4. Unix tarzı sistemlerde
+0

Soru, özellikle STDOUT’un ve STDERR’in aynı (dosya, terminal veya başka bir şekilde) ne zaman olduğunu tespit etmektir. –

+0

@JimStewart Niçin * neredeyse * dediğimi düşünüyorsunuz? Ve aynı dosyaya yönlendirme durumunda işe yaramadı uyardı? Yine de, lsof'un çıktısını ayrıştırmak gibi bir şey yapmadan yapabileceğiniz en iyisidir. – Ingo

+1

'(-t STDOUT)^(-t STDERR)' en azından bir terminale bir terminale gidip gitmeyeceğini söyleyecektir. Bu oldukça iyi bir başlangıç. – mob

İlgili konular