Bash'de stdin ve stdout yönlendirmesinin önceliği


9

Benim sorum yönlendirme önceliğiyle ilgili bash. Bir komutun olduğunu varsayın:

cmd1 < cmd2 > cmd3

Şuna çevirir mi:

(cmd1 < cmd2) > cmd3

Veya

cmd1 < (cmd2 > cmd3)

Yanıtlar:


11

POSIX standardı belirtir kabuk yönlendirme soldan sağa olduğunu; yani düzen önemlidir:

Yapı 2>&1genellikle standart hatayı standart çıktıyla aynı dosyaya yönlendirmek için kullanılır. Yeniden yönlendirmeler baştan sona gerçekleştiğinden, yeniden yönlendirme sırası önemlidir. Örneğin:

ls > foo 2>&1

hem standart çıktıyı hem de standart hatayı dosyaya yönlendirir foo. Ancak:

ls 2>&1 > foo

standart çıktı dosyaya yönlendirilmeden fooönce standart hata standart çıktı olarak kopyalandığından yalnızca standart çıktıyı dosyaya yönlendirir foo.

bash standardın bu kısmına uygun olarak çalışır:

$ ls doesnotexist > foo 2>&1
$ cat foo
ls: cannot access doesnotexist: No such file or directory
$ ls doesnotexist 2>&1 > foo
ls: cannot access doesnotexist: No such file or directory
$ cat foo
$ 

Borulama gelince:

Yönlendirme öncesi standart giriş veya standart çıkış veya her ikisinin ardışık düzen ataması gerçekleştiği için, yönlendirme ile değiştirilebilir. Örneğin:

$ command1 2>&1 | command2

standart çıkışını ve standart hatasını command1standart girişine gönderir command2.


Bu, Bash kabuğunun POSIX uyumlu olduğunu varsayar.
fpmurphy

1
Ben anlamıyorum. Siparişin soldan sağa olduğunu söylediğiniz için, ls > foo 2>&1stdout'u foo'ya yönlendirin, sonra stderr'ı stdout'a yönlendirin. Yani bu işe yaramaz. Benzer şekilde ikinci komut da çalışmalıdır. Burada ne eksik?
Deepak Mittal

1
@fpmurphy bash, varsayılan davranışın farklı olduğu, burada belirtilen durumlar haricinde, genellikle POSIX uyumludur bash. Daha bashuyumlu hale getirmek için --posixseçeneği kullanabilirsiniz .
Matt Eckert

@dpacmittal İlk örnek, şu şekilde ls > foo 2>&1çalışır: ilk olarak, standart çıktıya yeniden yönlendirilir foo, sonra standart hata şimdi dosya olan standart çıktıya yönlendirilir foo. İkinci örnek, şu şekilde ls 2>&1 > fooçalışır: standart çıktı yeniden yönlendirilmeden önce standart hata standart çıktıya yönlendirilir foo, bu nedenle dosyaya yönlendirilmek yerine standart hata yerel olarak yankılanır.
Matt Eckert

4
@dpacmittal .. yeniden ls 2>&1 >foo belki böyle düşünebilirsiniz. 'ls'den gelen stderr, stdout'a yönlendirilir. Bu olacak! Stdout ile ilgili diğer direktiflerden bağımsız olarak şu anda stdout'un atanmış olduğu yere gidecektir. (Çünkü bu onun asal / ilk direktifidir ) .. Sonra stdout'un "foo" ya gideceğini söyleyen başka bir direktif gelir, ve ... hatırla vermez: stderr sadece stdout'u nereye gider .. aslında olma stdout'a dönüşüyor değildir edildi direktifin anda atanmış. (örneğin, terminal)
Peter.O

4

Sanırım ikisi de değil. Bir çift parantez, bir alt kabuk anlamına gelir. Ancak bu durumda, yönlendirme nedeniyle hiçbir alt kabuk başlatılmayacaktır. Bash sadece cmd2stdin'e beslenir ve stdout'a beslenir cmd3.

Bence, böyle bir şey mi demek istiyorsun cmd1 | cmd2 | cmd3? Çünkü sizin cmd2ve cmd3"cmds" yerine genellikle normal dosyalardır.

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.