Czy można połączyć dane wyjściowe z tych dwóch poleceń?
node ~/projects/trunk/index.js
python ~/projects/trunk/run.py run
Żadne polecenie nie kończy się, więc nie jestem pewien, jak to zrobić.
bash
io-redirection
chovy
źródło
źródło
Odpowiedzi:
Możesz połączyć dwa polecenia, grupując je za pomocą
{ }
:do tej pory, można przekierować grupę do pliku (ostatni
;
przed}
jest obowiązkowe):jeśli chcesz oddzielić
STDOUT
iSTDERR
dwa pliki:źródło
;
przed}
, to jest obowiązkowe!{ yes {1..20} & yes {1..20}; } | grep -v '^1 2 3'
czemu idealnie nic nie wydrukujesz, jeśli linie nie zostaną złamane.&&
zamiast&
!command1 & command2
- to uruchamia polecenie 1 w tle i natychmiast uruchamia polecenie 2, tym samym uruchamiając oba polecenia równolegle i psując dane wyjściowe.command1 && command2
- uruchamia to polecenie 1 (na pierwszym planie), a następnie, jeśli polecenie 1 się powiedzie, uruchamia polecenie 2.Mówiąc bardziej ogólnie, można użyć grupowania podpowłoki lub grupowania poleceń i przekierować dane wyjściowe całej grupy naraz.
Kod:
( command1 ; command2 ; command3 ) | cat
{ command1 ; command2 ; command3 ; } > outfile.txt
Główna różnica między nimi polega na tym, że pierwszy dzieli proces potomny, podczas gdy drugi działa w kontekście głównej powłoki. Może to mieć konsekwencje w zakresie ustawiania i używania zmiennych i innych ustawień środowiska, a także wydajności.
Nie zapominaj, że nawias zamykający w grupowaniu poleceń (i funkcjach) musi być oddzielony od treści średnikiem lub znakiem nowej linii. Wynika to z faktu, że
"}"
tak naprawdę jest to samo polecenie (słowo kluczowe) i musi być traktowane jak jedno.źródło
( )
działa również dobrze.}
wcale nie jest poleceniem. To zastrzeżone słowo. To samo dotyczy{
. I zazwyczaj pisać takie listy tak:{ command1;command2;} > outfile.txt
. Możesz dodać spacje po średnikach, ale nie jest to konieczne. Konieczne{
jest jednak miejsce po .( yes {1..20} & yes {1..20}; ) | grep -v '^1 2 3'
czemu idealnie nic nie wydrukujesz, jeśli linie nie zostaną złamane. (H / t do @antak).( command1 && command2 && command3 ) | cat
()
jak w nawiasach klamrowych,{}
które działają jako postęp w tle, a następnie musisz poradzić sobie z tym. Również potok do kota `| cat` jest lepszą alternatywą niż `> / dev / stdout`Skończyło się na tym, inne sugestie nie zadziałały, ponieważ 2. polecenie zostało zabite lub nigdy nie zostało wykonane.
źródło
tail -f *.log
chociaż nigdy nie widziałem tego jako problemu z 2 różnymi procesami zapisującymi do tego samego pliku dziennika.yes {1..20}
polecenie2 =yes {1..20}
i potokować połączone wyjście, przez| grep -v '^1 2 3'
które idealnie nic nie wydrukujemy, jeśli linie nie zostaną podzielone. (H / t do @antak).Spróbuj tego:
źródło
Większość dotychczasowych rozwiązań źle radzi sobie z problemem częściowej linii. Załóżmy przez chwilę, że programami są:
Podczas uruchamiania tych równolegle chcesz, aby wynik zawierał pełne linie
a
s, po których następują pełne linieb
s. Czego nie chce toa
s ib
s mieszania w tej samej linii (tr -s ab
zastępuje powtarzająca
s przy pojedynczyma
, więc łatwiej jest zobaczyć, co się dzieje):Jeśli zamiast tego użyjesz GNU Parallel, uzyskasz ładne, czyste pełne linie z
a
s lubb
s, ale nigdy nie mieszane:Nowsze wersje GNU Parallel unikają nawet zapełniania dysku: powyższe może działać wiecznie.
źródło
Ponieważ już korzystasz
node
, możesz spróbować spróbować jednocześnieźródło
W specjalnym przypadku łączenia wielu danych wyjściowych poleceń BASH w jednym wierszu, oto przepis na uruchamianie każdego polecenia po kolei, usuwając wszelkie znaki nowej linii między ich wyjściami.
Jako przykład ze świata rzeczywistego poniższy kod osadzi komunikat ASCII między dwoma stałymi ciągami bajtów (w tym przypadku tworząc polecenie drukowania)
(Uwaga: ta metoda działa tylko wtedy, gdy polecenia kończą się. Aby połączyć standardowe wyjście z poleceń, które się nie kończą, zobacz inne odpowiedzi.)
źródło