BASH işlemindeki ikame neden bazı komutlarla çalışmıyor?


29

Bazı durumlarda işlem değişikliği beklendiği gibi çalışmayacaktır. İşte bir örnek:

Giriş:

gcc <(echo 'int main(){return 0;}')

Çıktı:

/dev/fd/63: file not recognized: Illegal seek
collect2: error: ld returned 1 exit status

Giriş:

Ancak farklı bir komutla kullanıldığında beklendiği gibi çalışır:

grep main <(echo 'int main(){return 0;}')

Çıktı:

int main(){return 0;}

Diğer komutlarda da benzer hatalar olduğunu fark ettim (örn. Dosyayı işlem değişikliğinden bekleten komut kullanılamaz /dev/fd/63veya benzeri değil ). İle bu başarısızlık gccsadece en son. Süreç ikame işleminin bu şekilde ne zaman başarısız olacağını ve kullanılmaması gerektiğini belirlemek için bilmem gereken bazı genel kurallar var mı?

Bu BASH sürümünü Ubuntu 12.04'te kullanıyorum (bunu arch ve debian'da da gördüm):
GNU bash, sürüm 4.3.11 (1) -turease (i686-pc-linux-gnu)


1
illegal seekcevap gibi görünüyor - |pipeo bashkadar yürütülen programa işaret eden bir aranabilir dosyası değil. muhtemelen echo data | command /dev/fd/0bir programda başarılı olamıyorsanız , w / 'da benzer bir şansınız olur <(cmd). Diskte bir dosya sağlamaz - sadece bir boru dosyası tanımlayıcısına işaret eden bir argüman yerine geçer.
mikeserv

2
Bu özel durumda, gcc standart girişi kabul edebilmesine rağmen , (varsayılan olarak) dili belirlemek için dosya adı uzantısını kullanır. Öyleyse dene gcc -xc <(echo 'int main(){return 0;}')(dili Caçıkça ayarlar ).
steeldriver

Bu soruyu yanıtlamak için buraya yönlendirildim, ki bunun bir başka örneği gibi görünüyor. superuser.com/questions/1243405 . Soruyu benden daha iyi ifade ettiğin için teşekkürler.
Jonathan Hartley

Yanıtlar:


33

İşlem değiştirme işlemi ( /dev/fd/63örneğinizde olduğu gibi) adlandırılmış bir borunun okunan ucu gibi davranan özel bir dosyayla sonuçlanır . Bu dosya açılıp okunabilir, ancak yazılmaz, aranmaz.

Argümanlarına saf akımlar gibi davranan komutlar kullanılırken, verilen dosyalarda arama yapmayı bekleyen komutlar (veya bunlara yazma) çalışmaz. : İrade işi genellikle bir filtre olarak kabul edilen olduğu komuta tür cat, grep, sed, gzip, awk, vb ... değil çalışma gibi bir editör olacak bir komut örneği viveya benzeri bir dosya işlemi mv.

gccHangi dilde yazıldıklarını belirlemek için giriş dosyalarına rasgele erişim sağlayabilmek istiyor. Bunun yerine gcc, giriş dosyasının dili hakkında bir ipucu verirseniz , dosyayı yayınlamaktan mutluluk duyarız:

gcc -x c <(echo 'int main(){return 0;}')

Proses ikamesi olmadan daha basit ve anlaşılır formu da işe yarar:

echo 'int main(){return 0;}' | gcc -x c -

Bunun kendine özgü olmadığını unutmayın bash. Proses ikamesini destekleyen tüm mermiler aynı şekilde davranır.


Gcc geçici çözümü için +1, ancak dosyalar konusundaki amacınızdan emin değilim. <()Biçimi tüm niyet ve amaçlar için bir dosya gibi hareket etmelidir. Aslında, memnun kalmayacak bir dosya bekleyen komutları bilmiyorum <(). Çalışmayanlar dosya adı bekleyenler, dosya değiller. Örneğin, grep -fbir dosya bekliyor ve ile iyi çalışıyor <().
terdon

4
@terndon Kesinlikle <()bir dosya adı üretir (yapı /proc/self/fd/somethingsistemimde genişler ). Bu ad, açıldığında, içinde bir destekleyici olan ve diğerlerini içermeyen S_IFIFOnormal bir dosya ( S_IFREG) yerine , adlandırılmış bir piponun ( ) okunan sonu gibi davranır . read()seek()
Celada

7
zshÖzellikle bu amaç için geçici dosyaları kullanan 3. bir işlem ikame biçimini desteklediğini unutmayın :gcc =(echo 'int main(){return 0;}')
Stéphane Chazelas

belki ilişkili , ancak birlikte çalıştığı ile <(echo '...')değil <(git show ...). Bunun neden olabileceği hakkında bir fikrin var mı?
Jörn Hees

2
GCC "hangi dilde yazıldığını tespit etmek için girdi dosyalarına rastgele erişim yapmaz". Sadece dosya adının uzantısına bakar. Dosya adı bir uzantıya sahip değilse (veya tanınmayan bir dosya varsa), GCC dosyanın bir nesne dosyası veya linker komut dosyası olduğunu varsayar ve bu dosyaya geçer ld(nesne biçimlerini algılar). -xbir ipucu değildir; bu bir bildiridir. Belirtirseniz -x f95, GCC, adını veya içeriğinden bağımsız olarak dosyayı Fortran-95 derleyicisine iletir. Bkz. Gcc.gnu.org/onlinedocs/gcc-8.1.0/gcc/Overall-Options.html
rici
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.