Evet, olduğu bash
gibi ksh
(özelliğin geldiği yer), işlem ikamesi içindeki süreçler için beklenmez (koddaki bir sonraki komutu çalıştırmadan önce).
Bir için <(...)
olduğu gibi ince, genellikle var biri:
cmd1 <(cmd2)
kabuk , yerine geçen borudaki dosya sonuna kadar okunması ve genellikle dosya sonu öldüğünde bu dosya sonu gerçekleşmesi için bekleyecek cmd1
ve cmd1
tipik olarak bekleyecektir . Yani birkaç kabukları (değil aynı neden ) bekleyen zahmet etmeyin de .cmd2
cmd2
bash
cmd2
cmd2 | cmd1
İçin cmd1 >(cmd2)
daha var olduğu, ancak, o, genellikle böyle değil cmd2
bekler o tipik cmd1
olacak genellikle çıkış sonrası bu yüzden orada.
Bu zsh
, cmd2
orada bekleyen sabittir (ancak yerleşik olarak yazdıysanız cmd1 > >(cmd2)
ve cmd1
yerleşik değilse, belgelenmiş{cmd1} > >(cmd2)
olarak kullanın ).
ksh
varsayılan olarak beklemez, ancak wait
yerleşik ile beklemenizi sağlar (ayrıca pid'i kullanılabilir hale getirir $!
, ancak bu yardımcı olmaz cmd1 >(cmd2) >(cmd3)
)
rc
( cmd1 >{cmd2}
sözdizimi ile), ksh
dışında tüm arka plan işlemlerinin pids'lerini alabilirsiniz $apids
.
es
(bu da cmd1 >{cmd2}
bekler için) cmd2
gibi zsh
, hem de bekler cmd2
içinde <{cmd2}
işlem yönlendirmeleri.
bash
pid'in cmd2
(ya da daha tam olarak alt kabuğun o alt kabuğun cmd2
bir alt işleminde çalıştığı gibi tam olarak alt kabuğun ) kullanılabilir olmasını sağlar $!
, ancak beklemenize izin vermez.
Kullanmak zorunda yoksa bash
, sen her iki komutlarını bekler bir komutu kullanarak sorunu çalışabilirsiniz:
{ { cmd1 >(cmd2); } 3>&1 >&4 4>&- | cat; } 4>&1
Bu her ikisini de yapar cmd1
ve cmd2
fd 3'lerini bir boruya açar. cat
dosya sonunu diğer uçta bekleyecek, bu nedenle genellikle yalnızca her ikisi de cmd1
ve cmd2
ölü olduğunda çıkacaktır . Ve kabuk bu cat
komutu bekleyecek . Tüm arka plan işlemlerinin sonlandırılmasını yakalamak için bir net olarak görebilirsiniz (bunu arka planla başlayan diğer şeyler için kullanabilirsiniz &
, coprocs veya arka planın kendileri gibi arka planın kendileri gibi tüm dosya tanımlayıcılarını kapatmazlarsa kullanabilirsiniz ).
Yukarıda bahsedilen boşa giden alt kabuk işlemi sayesinde cmd2
, fd 3'ü kapatsa bile çalıştığını unutmayın (komutlar genellikle bunu yapmaz, ancak bazıları beğenir sudo
veya ssh
yapar). Gelecekteki sürümleri bash
sonunda diğer kabuklarda olduğu gibi orada optimizasyonu yapabilir. O zaman şöyle bir şeye ihtiyacınız olacak:
{ { cmd1 >(sudo cmd2; exit); } 3>&1 >&4 4>&- | cat; } 4>&1
Hala bu fd 3 açık bu sudo
komutu bekleyen ekstra bir kabuk işlemi olduğundan emin olmak için .
Not cat
(süreçler kendi fd 3 yazmayın beri) bir şey okumazlar. Sadece senkronizasyon için var. Sonunda read()
hiçbir şey olmadan geri dönecek sadece bir sistem çağrısı yapacak.
cat
Boru senkronizasyonunu yapmak için bir komut ikamesi kullanarak çalışmayı gerçekten önleyebilirsiniz :
{ unused=$( { cmd1 >(cmd2); } 3>&1 >&4 4>&-); } 4>&1
Bu sefer, kabuk yerine var cat
olan diğer ucu arasında fd 3 açıktır borusundan okuyor cmd1
ve cmd2
. Çıkış durumu yüzden değişken atama kullanıyorsanız cmd1
mevcuttur $?
.
Ya da süreç ikamesini elle yapabilirsiniz ve daha sonra sisteminizi sh
standart kabuk sözdizimi haline gelecek şekilde bile kullanabilirsiniz :
{ cmd1 /dev/fd/3 3>&1 >&4 4>&- | cmd2 4>&-; } 4>&1
Ancak daha önce de belirtildiği gibi, tüm sh
uygulamaların bittikten cmd1
sonra beklemeyeceğine dikkat edin cmd2
(bu, diğer taraftan daha iyi olsa da). O zaman, $?
çıkış durumunu içerir cmd2
; gerçi bash
ve zsh
make cmd1
mevcuttur 'ın çıkış durumu ${PIPESTATUS[0]}
ve $pipestatus[1]
sırasıyla (ayrıca bkz pipefail
yani birkaç kabuklarda seçeneği $?
geçen dışındaki boru devrelerinin hasar bildirebilirsiniz)
yash
İşlem yeniden yönlendirme özelliğiyle benzer sorunları olduğunu unutmayın . orada cmd1 >(cmd2)
yazılır cmd1 /dev/fd/3 3>(cmd2)
. Ama beklemiyor ve onu beklemek için cmd2
kullanamazsınız wait
ve pid $!
değişkeni de kullanıma sunmaz. Etrafındaki işi aynı şekilde kullanırdınız bash
.