Bash: proses ikamesi ve stdin


13

Aşağıdaki satır açıktır:

echo "bla" | foo | bar

Ama aşağıdaki olanlar da aynı şeyi yapıyor mu?

echo "bla" | bar <(foo)
echo "bla" | bar < <(foo)

Hangi stdin gelen foove barokunan "bla" ve neden?

Yani, elbette, sadece kodlayabilir ve kontrol edebilirim, ancak tanımlanmış davranış olup olmadığından emin değilim ya da güvenmemem gereken özellikleri sömürüyorum.

Yanıtlar:


9

Bu kabuğa bağımlı ve belgelenmemiş AFAICS. Gelen kshve bash, birinci durumda, fooaynı Stdin paylaşacak bar. Çıkışı için savaşacaklar echo.

Örneğin,

$ seq 10000 | paste - <(tr 1 X)'
1       X
2       X042
3       X043
4       X044
5       X045
[...]

pasteDiğerlerini okurken, diğer tüm metin bloklarını seqçıktılarından okuyan kanıtlar görürsünüz tr.

İle zsh, dış stdin'i alır (bir terminal değilse ve kabuk etkileşimli değilse, bu durumda yönlendirilir /dev/null). ksh(kaynaklandığı yerde) zshve bashproses ikamesi AFAIK'i destekleyen tek Bourne benzeri kabuklardır.

In echo "bla" | bar < <(foo), not bar's stdin çıkış tarafından beslenen boru olacak foo. Bu iyi tanımlanmış bir davranış. Bu durumda, görünür foobireyin Stdin beslenen boru echotümünde ksh, zshve bash.

Her üç mermide de tutarlı bir davranışa sahip olmak ve geleceği kanıtlamak istiyorsanız, davranış belgelenmediği için değişebileceğinden, bunu yazarım:

echo bla | { bar <(foo); }

Emin olmak için foostdin de bir borudur echo(neden bunu yapmak istediğinizi anlayamıyorum). Veya:

echo bla | bar <(foo < /dev/null)

Yapmak için emin foogelmez değil gelen boru okunan echo. Veya:

{ echo bla | bar 3<&- <(foo <&3); } 3<&0

foo'Nin güncel versiyonlarında olduğu gibi dış stdin' e sahip olmak zsh.


"Bu durumda, foo'nun stdin tüm ksh, zsh ve bash yankı tarafından beslenen borudur." Bunu şimdi el ile test ettiniz mi, yoksa bir yerde belgelenmiş mi?
etam1024

İlk satırdaki "ilk durumda", "| foo | bar` veya `| bar <(foo) `?
Volker Siegel

4

echo "bla" | foo | bar: Çıktısı echo "bla"yönlendirilir foo, çıktısı yönlendirilir bar.

echo "bla" | bar <(foo): O bir boru çıkışı echo "bla"için bar. Ancak barbir tartışma ile idam edilir. Bağımsız değişken, çıktısının foogönderileceği dosya tanımlayıcısına giden yoldur . Bu bağımsız değişken, çıktısını içeren bir dosya gibi davranır foo. Yani, bu aynı değil.

echo "bla" | bar < <(foo): Çıktısının echo "bla"gönderilmesi gerektiği barve tüm ifadenin birincisine eşdeğer olduğu varsayılabilir . Ama bu doğru değil. Aşağıdakiler gerçekleşir: Giriş yeniden yönlendirmesi <borudan ( |) sonra gerçekleştirildiğinden , üzerine yazar . Yani echo "bla"bara bağlı değil. Bunun yerine, çıkışı foostandart giriş olarak yönlendirilir bar. Bunu temizlemek için aşağıdaki komut ve çıktıya bakın:

$ echo "bla" | cat < <(echo "foo")
foo

Gördüğünüz gibi echo "bla"yerini aldı echo "foo".

Şimdi şu komutu inceleyin:

$ echo "bar" | cat < <(awk '{printf "%s and foo", $0}')
bar and foo

Böylece echo "bar", stdin'i awkokuyan ve dizeye and fooçıktıya ekleyen piped edilir. Bu çıkışa yönlendirilir cat.


Ve sorum şu: " awk" bar "ı okuyan tanımlanmış bir davranış mı?"
etam1024

Evet öyle. cmd1 < <(cmd2)ile aynı şekilde davranır cmd2 | cmd1.
kaos

Veyacmd1 | cmd2 | cmd3cmd1 | cmd3 < <(cmd2)
kaos

3
Eğer wikipedia olsaydı, ifadelerinize "atıf gerekli" etiketi koyardım :) Sorumun asıl mesele sizin söylediğiniz gibi çalışması, ama bu konuda herhangi bir belge bulamadım.
etam1024
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.