Evet, olduğu bashgibi 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 cmd1ve cmd1tipik olarak bekleyecektir . Yani birkaç kabukları (değil aynı neden ) bekleyen zahmet etmeyin de .cmd2cmd2bashcmd2cmd2 | cmd1
İçin cmd1 >(cmd2)daha var olduğu, ancak, o, genellikle böyle değil cmd2bekler o tipik cmd1olacak genellikle çıkış sonrası bu yüzden orada.
Bu zsh, cmd2orada bekleyen sabittir (ancak yerleşik olarak yazdıysanız cmd1 > >(cmd2)ve cmd1yerleşik değilse, belgelenmiş{cmd1} > >(cmd2) olarak kullanın ).
kshvarsayılan olarak beklemez, ancak waityerleş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), kshdışında tüm arka plan işlemlerinin pids'lerini alabilirsiniz $apids.
es(bu da cmd1 >{cmd2}bekler için) cmd2gibi zsh, hem de bekler cmd2içinde <{cmd2}işlem yönlendirmeleri.
bashpid'in cmd2(ya da daha tam olarak alt kabuğun o alt kabuğun cmd2bir 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 cmd1ve cmd2fd 3'lerini bir boruya açar. catdosya sonunu diğer uçta bekleyecek, bu nedenle genellikle yalnızca her ikisi de cmd1ve cmd2ölü olduğunda çıkacaktır . Ve kabuk bu catkomutu 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 sudoveya sshyapar). Gelecekteki sürümleri bashsonunda 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 sudokomutu 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.
catBoru 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 catolan diğer ucu arasında fd 3 açıktır borusundan okuyor cmd1ve cmd2. Çıkış durumu yüzden değişken atama kullanıyorsanız cmd1mevcuttur $?.
Ya da süreç ikamesini elle yapabilirsiniz ve daha sonra sisteminizi shstandart 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 shuygulamaların bittikten cmd1sonra beklemeyeceğine dikkat edin cmd2(bu, diğer taraftan daha iyi olsa da). O zaman, $?çıkış durumunu içerir cmd2; gerçi bashve zshmake cmd1mevcuttur 'ın çıkış durumu ${PIPESTATUS[0]}ve $pipestatus[1]sırasıyla (ayrıca bkz pipefailyani 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 cmd2kullanamazsınız waitve pid $!değişkeni de kullanıma sunmaz. Etrafındaki işi aynı şekilde kullanırdınız bash.