bash içindeki iki komutun çıktısını birleştir


81

Bu iki komutun çıktısını birleştirmek mümkün mü?

node ~/projects/trunk/index.js 
python ~/projects/trunk/run.py run

Her iki komut da çıkmaz, bu yüzden bunun nasıl yapılacağından emin değilim.


3
Programlar bitmiyorsa, muhtemelen sürekli olarak çıktı mı yazıyorlar? Çıktılarıyla ne yapmak istersin? Serpiştirme hatları, ...? Bunu neden yapmak istiyorsun?
vonbrand

2
Düğüm komutu çok fazla çıktı vermiyor ancak yine de çalışması gerekiyor. Python one tüm istekleri verir, ikisini de yakalamak ve ikisini de aynı kabuk penceresinde izlemek istiyorum.
Chovy

Yanıtlar:


108

İki komutu bir grupla birleştirerek birleştirebilirsiniz { }:

{ command1 & command2; }

şu ana kadar grubu bir dosyaya yönlendirebilirsiniz (daha ;önce }zorunludur):

{ command1 & command2; } > new_file

Eğer ayırmak istiyorum STDOUTve STDERRiki dosyalarında:

{ command1 & command2; } > STDOUT_file 2> STDERR_file

3
Programlarının bitmediği önemli değil. 'tail -f' da "bitirmez", ancak bu hala çalışır ve her iki programın çıktılarını birleştirir. İkiden fazla komut için de çalışır. ^ c çıkmak için gruplandırılmış komutlardan yalnızca birini öldürür. Yine de diğerinin el ile öldürmek zorunda kalacaksın.
SuperMagic

5
Geçen eksikliği gibi görünüyor ;önce }, zorunlu değil!
Gilles Quenot

2
Dikkatli olun: Bu, tüm çizgileri korumaz! Satırlar kısmen bölündüğü ve birbirleri ile karıştığı için güvenilmez çıktılar elde edersiniz. { yes {1..20} & yes {1..20}; } | grep -v '^1 2 3'Çizgiler kırılmazsa, ideal olarak hiçbir şeyi yazdırmayacak olanları deneyebilirsiniz .
17:17

8
Yerine kullanmayı &&tercih ederim &! command1 & command2- bu, komut1'i arka planda çalıştırır ve hemen komut2'yi başlatır, böylece her iki komutu da paralel olarak çalıştırır ve çıktıyı karıştırır. command1 && command2- bu, komut1'i (ön planda) çalıştırır ve ardından komut1 başarılı olursa, komut2'yi çalıştırır.
DUzun

1
@DUzun OP, hiçbir komutun da çıkmadığını söyledi, bu nedenle çözümünüzle ikinci komut asla çalışmayacak
Zoey Hewll

50

Daha genel olarak, bir alt kabuk veya komut grubu kullanmak ve tüm grubun çıktısını bir kerede yönlendirmek mümkündür.

Kod:

( command1 ; command2 ; command3 ) | cat

{ command1 ; command2 ; command3 ; } > outfile.txt

İkisi arasındaki temel fark, birincisinin bir çocuk sürecine bölünmesi, ikincisinin ise ana kabuk bağlamında çalışmasıdır. Bunun, değişkenlerin ve diğer ortam ayarlarının yanı sıra performansın ayarlanması ve kullanılmasıyla ilgili sonuçları olabilir.

Unutmayın, komut grubundaki (ve fonksiyonlardaki) kapanış dirsekleri içeriklerden noktalı virgül ya da yeni satır ile ayrılmalıdır. Bunun nedeni "}"aslında kendi başına bir komut (anahtar kelime) olması ve bunun gibi davranılması gerektiğidir.


2
İşlerden yönlendirme de ( )gayet iyi.
muru

2
}hiç bir komut değil. Ayrılmış bir kelime. Aynı şey için de geçerli {. Genellikle şöyle böyle listeler yazmak: { command1;command2;} > outfile.txt. Noktalı virgüllerden sonra boşluk ekleyebilirsiniz, ancak bu gerekli değildir. Uzay sonra { ise de, gerekli.
Wildcard

1
Dikkatli olun: Bu, tüm çizgileri korumaz! Satırlar kısmen bölündüğü ve birbirleri ile karıştığı için güvenilmez çıktılar elde edersiniz. ( yes {1..20} & yes {1..20}; ) | grep -v '^1 2 3'Çizgiler kırılmazsa, ideal olarak hiçbir şeyi yazdırmayacak olanları deneyebilirsiniz . (H / t @antak).
Ole Tange

3
Bazen ( command1 && command2 && command3 ) | cat
komut2'yi

yuvarlak parantezleri (), {}arkaplan ilerlemesi olarak çalıştıran kıvrımlı parantezlerde olduğu gibi tercih ediyorum ve ondan çıktılarla başa çıkmak zorundasınız. Ayrıca kedi `pipo | kedi daha güzel bir alternatiftir, sonra>> / dev / stdout`
DarkMukke

2

Bunu yapmayı bitirdim, diğer öneriler işe yaramadı, çünkü 2. emir ya öldürüldü ya da hiç uygulanmadı.

alias app () {
    nohup python ~/projects/trunk/run.py run 1>/tmp/log 2>&1 &
    echo $! > /tmp/api.pid
    nohup node ~/projects/trunk/index.js 1>/tmp/log 2>&1 &
    echo $! > /tmp/client.pid
    tail -f /tmp/log
}

1
Not: Bu, iki işlem "aynı anda" dosyaya yazmaya çalışırsa G / Ç hatalarına neden olabilir.
Djizeus,

2
2 farklı günlük dosyası belirtebilir ve bunu tail -f *.logaynı günlük dosyasına yazan 2 farklı işlemle ilgili bir sorun olarak görmemiş olmama rağmen yapabilirim .
chovy

@chovy: sorununuzu burada soru olarak yazabilir misiniz ... faydalıdır
Abdennour TOUMI

1
Dikkatli olun: Bu, tüm çizgileri korumaz! Satırlar kısmen bölündüğü ve birbirleri ile karıştığı için güvenilmez çıktılar elde edersiniz. Bunu command1 = yes {1..20}command2 = ile deneyebilir yes {1..20}ve birleştirilen çıktıyı, | grep -v '^1 2 3'çizgiler kırılmadığında ideal olarak hiçbir şey yazdırmayacak şekilde yönlendirebilirsiniz. (H / t @antak).
Ole Tange

Bunun üzerine, eğer veri miktarı büyükse, diskiniz dolu olabilir.
Ole Tange

2

Bunu dene:

paste $(node ~/projects/trunk/index.js) $(python ~/projects/trunk/run.py run) > outputfile

1
'yapıştır' ne yapar?
Chovy

@chovy, buraya bakın: techrepublic.com/article/… Bu bağlamda çalışıp çalışmayacağından emin değilim.
FixMaker

Yapıştırmanın burada uygun olduğunu sanmıyorum, çünkü birbirlerinin yanına sütun koymak gerekiyor
Bernhard

@Bernhard gerçekten. Ancak req's belirtilen değildi
frogstarr78

@ frogstarr78 Ben onun istediği bu pek olası değildir bence, ama haklısın, belirtilmemiş.
Bernhard

1

Şimdiye kadar çözümlerin çoğu kısmi çizgi problemi ile çok kötü bir şekilde ilgileniyor. Programların bir saniye olduğunu varsayalım:

cmd1() {
    perl -e 'while(1) { print "a"x3000_000,"\n"}'
}
export -f cmd1
cmd2() {
    perl -e 'while(1) { print "b"x3000_000,"\n"}'
}
export -f cmd2

Bunları paralel olarak çalıştırırken çıktının tam as satırının ardından tam s satırının olmasını istersiniz b. Ne yapmak değil istemek olduğunu alar ve baynı satırda karıştırma lar ( tr -s abtekrarlayan yerini aler tek olan a, yüzden ne olacağını görmek daha kolaydır):

# This is bad - half lines are mixed
$ (cmd1 & cmd2 ) | tr -s ab
bababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababa
ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab

Bunun yerine GNU Parallel kullanıyorsanız, as veya bs tuşlarıyla temiz ama tam çizgiler elde edersiniz, ancak asla karıştırmazsınız:

$ parallel --line-buffer ::: cmd1 cmd2 | tr -s ab
a
a
b
b
b
b
a

GNU Parallel'un yeni sürümleri bile diskinizi doldurmaktan kaçınır: Yukarıdakiler sonsuza dek çalışabilir.


0

Zaten kullandığınız için node, eşzamanlı olarak denemek isteyebilirsiniz

Aynı anda birden fazla komut çalıştırın. Gibi npm run watch-js & npm run watch-lessama daha iyi.


0

Birden fazla BASH komut çıkışını bir satıra birleştirmek için özel durum için, her bir komutu sırayla çalıştırmak ve çıkışları arasındaki tüm yeni satırları kaldırmak için bir reçete.

(echo 'ab' && echo 'cd' && echo 'ef') | tr -d '\n'
>>> abcdef

Gerçek dünyadan bir örnek olarak, aşağıdaki kod iki sabit bayt dizisi arasına bir ASCII mesajı yerleştirecektir (bu durumda bir baskı komutu oluşturarak)

#   hex prefix           encode a message as hex    hex suffix    | strip newline | hex to binary | (then, for example, send the binary over a TCP connection)
(echo '1b40' && echo "Test print #1" | xxd -p && echo '1d564103') | tr -d '\n'    | xxd -r -p     | nc -N 192.168.192.168 9100

(Not: bu yöntem yalnızca komutlar çıktığında çalışır. Çıkmaz komutlarından stdout komutunu birleştirmek için diğer yanıtlara bakın.)


(1) Lütfen ikinci komutunuzun (beklenen) çıktısını gösterin. (2) Lütfen OP'nin bu tekniği problemini çözmek için nasıl kullanacağını gösterin.
Scott,

1) İkinci komutun çıktısı ascii olmayan ikilidir, bu nedenle gösterilmesi faydalı olmaz. 2) OP muhtemelen 2013 ile şimdi arasındaki özel problemini çözdü. Bu soru artık etkin bir şekilde birden fazla Bash komutunun stdout'unu bir araya getirme referansıdır, bu yüzden onları tek bir satırda birleştirme tekniğinin burada bahsedilecek kullanışlı bir "tarif" olduğuna inanıyorum (buraya onu aramaya geldiğim için bulamadım. o).
Luke,
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.