eseguire l'output di uno script come un comando autonomo bash
Domanda
si supponga di avere uno script Perl "foobar.pl" che stampa il seguente stdout
date -R
e si desidera eseguire tutto ciò che le uscite di script Perl come un comando autonomo bash (non preoccuparti di problemi di sicurezza come questo è in esecuzione in un ambiente fidato).
Come si arriva bash a riconoscere questo come un comando autonomo?
Ho provato con xargs, ma che sembra voler passare argomenti solo a un comando predefinito.
Voglio che lo script in Perl per essere in grado di uscita qualsiasi comando arbitrario.
$command = 'date -R'
system($command); ## in the perl script
È possibile che questo non funziona perché voglio che venga eseguito in un ambiente cygwin esistente ...
foobar.pl | xargs bash -i {}
È possibile che questo non funziona perché bash sembra essere in esecuzione un nuovo processo e, quindi, l'inizializzazione e le impostazioni da bash_profile non ottenere un'istanza.
Soluzione
Bad:
`perl foo.pl`
$(perl foo.pl)
Perché questo è male? A causa dei tanti motivi; in particolare:
- Wordsplitting: Che cosa stai facendo qui sta prendendo l'uscita dello script Perl, dividendo in pezzi ovunque ci siano spazi, tabulazioni o ritorni a capo, e prendendo quei pezzi come argomenti del primo blocco, che è il comando da eseguire. In casi veramente estremamente semplicistici come
$(echo 'date +%s')
potrebbe funzionare; ma questo è solo una pessima rappresentazione di ciò che si sta facendo veramente qui. - Non si può fare, citando o utilizzare qualsiasi altra caratteristica della shell
bash
come espansione di parametro, le parole chiave bash, ecc.
Buono, ma scomodo:
perl foo.pl > mytmpfile; bash mytmpfile
La creazione di un file temporaneo per mettere l'uscita del vostro script perl in e quindi eseguire che con bash funziona, ma è scomoda perché è necessario creare (e ripulire!) Il vostro file temporaneo e lo hanno in un portabile scrivibile (e sicuro! ) posizione.
Ricorda anche di non usare .
o source
per eseguire il file temporaneo a meno che realmente intende eseguire il tutto nella shell attiva. Inoltre, quando si utilizza .
o source
, non sarà in grado di pulire in modo affidabile il vostro file temporaneo in seguito.
Probabilmente la migliore soluzione:
perl foo.pl | bash
Questo è abbastanza sicuro a tutto tondo ( "sicuro" nel contesto, almeno soggetto ad errori) supponendo che l'uscite script Perl sintassi corretta bash, naturalmente.
Alternative che fare più o meno la stessa cosa:
bash < <(perl foo.pl)
bash <(perl foo.pl)
Altri suggerimenti
`foobar.pl`
Dato il file perl:
print "date";
il seguente comando bash lo farà.
> $(perl qq.pl)
Mon Apr 6 11:02:07 WAST 2009
Ma che viene eseguito in una shell separata. Se davvero si vuole invocare nel contesto del corrente shell, fare questo:
$ perl qq.pl >/tmp/qq.$$ ; . /tmp/qq.$$ ; rm -f /tmp/qq.$$
Mon Apr 6 11:04:59 WAST 2009
Prova:
foobar.pl | bash
Non credo che questo è esattamente ciò che stai cercando, ma la sua quello che ho: -)
perl foo.pl > /tmp/$$.script; bash /tmp/$$.script; rm /tmp/$$.script
In bocca al lupo!
Prova con Open ($ fh, "- |", $ arg1, arg2 $)