È possibile combinare l'output di questi due comandi?
node ~/projects/trunk/index.js
python ~/projects/trunk/run.py run
Nessuno dei due comandi esce quindi non sono sicuro di come farlo.
È possibile combinare l'output di questi due comandi?
node ~/projects/trunk/index.js
python ~/projects/trunk/run.py run
Nessuno dei due comandi esce quindi non sono sicuro di come farlo.
Risposte:
È possibile combinare due comandi raggruppandolo con { }
:
{ command1 & command2; }
finora, puoi reindirizzare il gruppo su un file (l'ultimo ;
prima }
è obbligatorio):
{ command1 & command2; } > new_file
se vuoi separare STDOUT
e STDERR
in due file:
{ command1 & command2; } > STDOUT_file 2> STDERR_file
;
prima di }
, è obbligatoria!
{ yes {1..20} & yes {1..20}; } | grep -v '^1 2 3'
quale idealmente non stampa nulla se le linee non sono interrotte.
&&
invece di &
! command1 & command2
- questo esegue command1 in background e avvia command2 immediatamente, quindi eseguendo entrambi i comandi in parallelo e rovinando l'output. command1 && command2
- questo esegue command1 (in primo piano) e quindi, se command1 ha successo, esegue command2.
Più in generale, è possibile utilizzare una subshell o un raggruppamento di comandi e reindirizzare contemporaneamente l'output dell'intero gruppo.
Codice:
( command1 ; command2 ; command3 ) | cat
{ command1 ; command2 ; command3 ; } > outfile.txt
La differenza principale tra i due è che il primo si divide in un processo figlio, mentre il secondo opera nel contesto della shell principale. Ciò può avere conseguenze sull'impostazione e l'uso di variabili e altre impostazioni dell'ambiente, nonché sulle prestazioni.
Non dimenticare che la parentesi di chiusura nel raggruppamento di comandi (e funzioni) deve essere separata dal contenuto con un punto e virgola o una nuova riga. Questo perché in "}"
realtà è un comando (parola chiave) a sé stante e deve essere trattato come tale.
( )
funziona bene.
}
non è affatto un comando. È una parola riservata. Lo stesso vale per {
. Io di solito scrivo queste liste in questo modo: { command1;command2;} > outfile.txt
. È possibile aggiungere spazi dopo il punto e virgola ma non è necessario. Lo spazio dopo {
è necessario, però.
( yes {1..20} & yes {1..20}; ) | grep -v '^1 2 3'
quale idealmente non stampa nulla se le linee non sono interrotte. (Da H / t a @antak).
( command1 && command2 && command3 ) | cat
()
come con le parentesi graffe {}
che corre come un progresso in background e quindi devi gestire l'output da quello. Anche pipe to cat `| cat` è un'alternativa più piacevole di `> / dev / stdout`
Ho finito per farlo, gli altri suggerimenti non hanno funzionato, dato che il secondo comando è stato ucciso o mai eseguito.
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
}
tail -f *.log
sebbene non abbia mai visto questo come un problema con 2 processi diversi che scrivono nello stesso file di registro.
yes {1..20}
command1 = command2 = yes {1..20}
e reindirizzare l'output combinato attraverso il | grep -v '^1 2 3'
quale idealmente non stampa nulla se le linee non sono interrotte. (Da H / t a @antak).
Prova questo:
paste $(node ~/projects/trunk/index.js) $(python ~/projects/trunk/run.py run) > outputfile
La maggior parte delle soluzioni finora affronta male il problema della linea parziale. Supponiamo per un secondo che i programmi siano:
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
Quando si eseguono quelli in parallelo, si desidera che l'output abbia linee complete di a
s seguite da linee complete di b
s. Quello che non vuoi è mescolare a
s e b
s sulla stessa linea ( tr -s ab
sostituisce la ripetizione di a
s con un singolo a
, quindi è più facile vedere cosa succede):
# This is bad - half lines are mixed
$ (cmd1 & cmd2 ) | tr -s ab
bababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababa
ababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab
Se invece usi GNU Parallel, otterrai delle linee piene e pulite con a
s o b
s ma mai mescolate:
$ parallel --line-buffer ::: cmd1 cmd2 | tr -s ab
a
a
b
b
b
b
a
Le versioni più recenti di GNU Parallel evitano addirittura di riempire il disco: quanto sopra può funzionare per sempre.
Dal momento che stai già utilizzando node
, potresti voler provare contemporaneamente
Esegui più comandi contemporaneamente. Piace
npm run watch-js & npm run watch-less
ma meglio.
Per il caso speciale di combinare più output di comando BASH su una riga, ecco una ricetta per eseguire ogni comando a turno, rimuovendo eventuali nuove righe tra i loro output.
(echo 'ab' && echo 'cd' && echo 'ef') | tr -d '\n'
>>> abcdef
Come esempio del mondo reale, il codice seguente incorporerà un messaggio ASCII tra due stringhe fisse di byte (formando un comando di stampa, in questo caso)
# 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
(Nota: questo metodo funziona solo se i comandi escono. Per combinare stdout da comandi che non escono, vedere altre risposte.)