2010-07-30 19 views
5

Ho notato che quando uso backtick in perl i comandi vengono eseguiti usando sh, non bash, dandomi alcuni problemi.backlks perl: usare bash invece di sh

Come posso modificare il comportamento in modo che perl utilizzi bash?

PS. Il comando che sto cercando di eseguire è:

paste filename <(cut -d \" \" -f 2 filename2 | grep -v mean) >> filename3 
+0

Sono quasi certo che la risposta è "non si". – tster

+0

perché? Qual è il tuo understatement? –

+0

'sh' è universale,' bash' non lo è. – Amadan

risposta

7

Prova

`bash -c \"your command with args\"` 

Sono abbastanza sicuro che l'argomento del -c viene interpretato il modo bash interpreta la sua linea di comando. Il trucco è proteggerlo da sh - ecco a cosa servono le virgolette.

+0

Ora sto ricevendo errori come -f 1/tmp/file | grep -v mean) >>/tmp/file2: -c: linea 0 : EOF inaspettato durante la ricerca di corrispondenza ') ' -f 1/tmp/file3 | grep -v mean) >>/tmp/file4: -c: riga 1: errore di sintassi: fine imprevista del file –

+0

Nel mio esempio potrebbero non essere \ necessari. Inoltre, non usare "dentro il tuo comando - usa" – Arkadiy

+1

SOLVED! L'unica cosa che ha funzionato per me è stata: '\' bash -c 'my_command' \ '' –

7

La "shell di sistema" non è generalmente modificabile. Vedere perldoc -f exec:

If there is more than one argument in LIST, or if LIST is an array with more than one value, calls execvp(3) with the arguments in LIST. If there is only one scalar argument or an array with one element in it, the argument is checked for shell metacharacters, and if there are any, the entire argument is passed to the system's command shell for parsing (this is "/bin/sh -c" on Unix platforms, but varies on other platforms).

Se avete veramente bisogno bash per eseguire un compito particolare, considerano definendola esplicitamente:

my $result = `/usr/bin/bash command arguments`; 

o anche:

open my $bash_handle, '| /usr/bin/bash' or die "Cannot open bash: $!"; 
print $bash_handle 'command arguments'; 

Si potrebbe anche mettere i comandi bash in un file .sh e invocarlo direttamente:

my $result = `/usr/bin/bash script.pl`; 
+0

Non riesco ancora a ottenere il comportamento previsto. Il motivo per cui volevo bash è che eseguo il comando ac usando <(grep ...) e sembra che sh non lo supporti (ma bash lo fa). Se eseguo il mio comando come utente, direttamente da bash funziona correttamente. Se lo eseguo da perl in apici inverso sh grida "sh: Errore di sintassi:" ("imprevisto", se lo eseguo in apici preceduti da/usr/bin/bash ottengo sempre la stessa cosa da sh –

+0

@David: Non capisco esattamente quale comando stai cercando di eseguire, puoi modificarlo nella tua domanda con la formattazione del codice? – Ether

0

Ho pensato che la variabile onorasse la variabile $SHELL, ma poi mi è venuto in mente che il suo comportamento potrebbe effettivamente dipendere dall'implementazione exec del sistema. Nel mio, sembra che exec

will execute the shell (/bin/sh) with the path of the file as its first argument.

si può sempre fare qw/bash your-command/, no?

+0

Ricevo ancora "sh: Errore di sintassi:" ("imprevisto". Vedi un commento sul post originale per il comando che cerco di eseguire. –

4

Questo esempio funziona per me:

$ perl -e 'print `/bin/bash -c "echo <(pwd)"`' 
/dev/fd/63 
+0

questo funziona anche per me ... –

0

Creare una subroutine Perl:

sub bash { return `cat << 'EOF' | /bin/bash\n$_[0]\nEOF\n`; } 

e usarlo come di seguito:

my $bash_cmd = 'paste filename <(cut -d " " -f 2 filename2 | grep -v mean) >> filename3'; 
print &bash($bash_cmd); 

Oppure usare perl qui-doc per il multi-linea di comandi:

$bash_cmd = <<'EOF'; 
    for ((i = 0; i < 10; i++)); do 
     echo "${i}" 
    done 
EOF 
print &bash($bash_cmd); 
Problemi correlati