Geçici dosyalar olmadan iki programdan farklı çıktı


Yanıtlar:


213

<(command)Bir komutun çıktısını başka bir programa bir dosya adıymış gibi iletmek için kullanın . Bash, programın çıktısını bir boruya aktarır ve /dev/fd/63dış komutta olduğu gibi bir dosya adı iletir.

diff <(./a) <(./b)

Benzer şekilde , bir >(command)şeyi bir komuta yönlendirmek istiyorsanız kullanabilirsiniz .

Buna Bash'in man sayfasında "Süreç Değiştirme" denir.


2
Dikkat edilmesi gereken bir dezavantaj, ./a veya ./b başarısız olursa, arayanın bunu bulamayacağıdır.
Alexander Pogrebnyak

5
OP, bash sorusunu etiketledi, ancak kayıt için bu başka bir kabukta çalışmıyor. Posix yardımcı program standardının bir bash uzantısıdır.
DigitalRoss

5
Ben bir Java programı ile bu çözümü denedim ve bu hata var: -bash: syntax error near unexpected token ('. Parantez olmadan tekrar denedim ve aldım -bash: java: No such file or directory. Komutun parametreleri varsa çalışmıyor mu?
styfle

1
@DigitalRoss - Çözüm, bir takma ad kullanılarak diğer kabuklara genişletilebilir. Tcsh, aşağıdaki çirkinlik çalışır: alias diffcmd bash -c \'diff \<\(sh -c \!:1\) \<\( sh -c \!:2 \)\'. (Sonra, örneğin: diffcmd "ls" "ls -a").
Paul Lynch

Google dışında dolaşan herkes için bu aynı zamanda zsh altında da çalışır. (Ayrıca, çağıran bir şeye girdi beslemeniz gerekiyorsa fseek, zsh, =(./a)aynı şekilde kullanılabilen <(./a)ancak başlık altında geçici bir dosya kullanan,
zsh'nin

26

Her iki yanıta da ekleyerek, yan yana karşılaştırma görmek istiyorsanız, şunu kullanın vimdiff:

vimdiff <(./a) <(./b)

Bunun gibi bir şey:

görüntü açıklamasını buraya girin


vimdiffgüzel, akıllı ve etkileşimli fark karşılaştırma görünümleri oluşturur. vimÇoğu sistemde paketle birlikte geliyor gibi görünüyor .
Tim Visée

vimdiffaynı zamanda yalnızca farklı olan satırı değil, aynı zamanda farklı olan belirli metin parçasını da gösterir.
Anton Tarasenko


15

Merak eden herkes için, Balık kabuğunu kullanırken işlem ikamesini şu şekilde gerçekleştirirsiniz :

Bash:

diff <(./a) <(./b)

Balık:

diff (./a | psub) (./b | psub)

Ne yazık ki balıktaki uygulama şu anda yetersiz ; fish ya asılır ya da diskte geçici bir dosya kullanır. Ayrıca komutunuzdan çıktı almak için psub kullanamazsınız.


Bu şu anda balıkta doğru çalışmıyor. Programların çıktısı birden fazla BUFSIZ ise, komut askıda kalacaktır. (veya balık aslında diskteki geçici bir dosyayı kullanır)
Evan Benn

7

Zaten iyi olan cevaplara biraz daha eklemek (bana yardımcı oldu!):

Komut dockeryardımının çıktısını verir STD_ERR(yani dosya tanımlayıcısı 2)

Görmek istedim docker attachve docker attach --helpaynı çıktıyı verdim

$ docker attach

$ docker attach --help

Bu iki komutu henüz yazdıktan sonra aşağıdakileri yaptım:

$ diff <(!-2 2>&1) <(!! 2>&1)

!! ! -1 ile aynıdır, yani bundan önce 1 komutunu çalıştırın - son komut

! -2, bundan önce iki komutu çalıştır anlamına gelir

2> & 1, file_descriptor 2 çıktısını (STD_ERR) file_descriptor 1 çıktısıyla (STD_OUT) aynı yere göndermek anlamına gelir

Umarım bunun bir faydası olmuştur.


0

Zsh için kullanmak, =(command)otomatik olarak geçici bir dosya oluşturur =(command)ve dosyanın kendi yoluyla değiştirir. Normal Süreç Değiştirme $(command)ile , komutun çıktısı ile değiştirilir .

Bu zsh özelliği çok kullanışlıdır ve bir diff aracı kullanarak iki komutun çıktısını karşılaştırmak için bu şekilde kullanılabilir, örneğin Karşılaştırmanın Ötesinde:

bcomp  =(ulimit -Sa | sort) =(ulimit -Ha | sort)

Karşılaştırmanın Ötesinde bcompiçin , karşılaştırmayı başlattığından ve tamamlanmasını beklediğinden yukarıdakiler için (yerine bcompare) kullanmanız gerektiğini unutmayın . Eğer kullanırsanız , oluşturulan geçici dosyalar komutların çıktısını depolamak için hangi nedeniyle o başlattı karşılaştırma ve hemen çıkışlar kaybolur.bcompbcompare

Daha fazlasını buradan okuyun: http://zsh.sourceforge.net/Intro/intro_7.html

Ayrıca şuna dikkat edin:

Kabuğun geçici bir dosya oluşturduğunu ve komut bittiğinde dosyayı sildiğini unutmayın.

ve aşağıdakiler arasındaki fark $(...)ve =(...):

Zsh'ın man sayfasını okursanız, <(...) 'nin = (...)' ye benzer başka bir süreç ikame biçimi olduğunu fark edebilirsiniz. İkisi arasında önemli bir fark var. <(...) durumunda, kabuk bir dosya yerine adlandırılmış bir kanal (FIFO) oluşturur. Dosya sistemini doldurmadığından bu daha iyidir; ama her durumda çalışmıyor. Aslında, yukarıdaki örneklerde = (...) 'yi <(...) ile değiştirseydik, fgrep -f <(...) dışında hepsi çalışmayı durdururdu. Bir boruyu düzenleyemez veya bir posta klasörü olarak açamazsınız; Bununla birlikte, fgrep'in bir pipodan bir kelime listesini okumakta hiçbir sorunu yoktur. Foo | den beri diff <(foo) çubuğunun neden çalışmadığını merak edebilirsiniz. diff - bar çalışmaları; bunun nedeni, diff'in bağımsız değişkenlerinden birinin - olduğunu fark ederse geçici bir dosya oluşturması ve ardından standart girdisini geçici dosyaya kopyalamasıdı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.