2010-07-30 16 views
5

Me di cuenta de que cuando uso los backticks en perl los comandos se ejecutan usando sh, no bash, lo que me da algunos problemas.perl backticks: use bash en lugar de sh

¿Cómo puedo cambiar ese comportamiento para que perl use bash?

PS. El comando que intento ejecutar es:

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

Estoy bastante seguro de que la respuesta es "usted no". – tster

+0

¿por qué? ¿Cuál es su subestimación? –

+0

'sh' es universal,' bash' no lo es. – Amadan

Respuesta

7

Trate

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

Estoy bastante seguro de que el argumento de -c se interpreta de la manera fiesta interpreta su línea de comandos. El truco es protegerlo de sh - para eso son las cotizaciones.

+0

Ahora recibo errores como -f 1/tmp/file | grep -v mean) >>/tmp/file2: -c: line 0 : EOF inesperado mientras busca la coincidencia ') ' -f 1/tmp/file3 | grep -v mean) >>/tmp/file4: -c: línea 1: error de sintaxis: final inesperado del archivo –

+0

Puede ser \ no necesario en mi ejemplo. Además, no use "dentro de su comando - use '. – Arkadiy

+1

¡SOLUCIONADO! Lo único que funcionó para mí fue' 'bash -c' mi_comando '\' ' –

7

El "shell del sistema" no es generalmente mutable. Ver 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).

Si realmente necesita bash para realizar una tarea en particular, considere llamar explícitamente:

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

o incluso:

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

También puede poner sus comandos de bash en un archivo .sh e invocar eso directamente:

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

Todavía no puedo obtener el comportamiento esperado. La razón por la que quería bash es porque ejecuto el comando ac usando <(grep ...) y parece que sh no lo admite (pero bash lo hace). Si ejecuto mi comando como usuario, directamente desde bash, funciona bien. Si lo ejecuto desde perl en backticks, sh shouts "sh: Error de sintaxis:" ("inesperado", si lo ejecuto en backticks precedidos por/usr/bin/bash, sigo obteniendo lo mismo de sh –

+0

@David: No entiendo muy bien qué comando está intentando ejecutar, ¿puede editarlo en su pregunta con el formato del código? – Ether

0

Pensé que perl cumpliría con la variable $SHELL, pero luego se me ocurrió que su comportamiento en realidad podría depender de la implementación exec de su sistema. En la mía, parece que exec

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

Siempre se puede hacer qw/bash your-command/, ¿no?

+0

Todavía me sale "sh: Error de sintaxis:" ("inesperado". Vea un comentario en la publicación original de el comando que trato de ejecutar. –

4

Este ejemplo funciona para mí:

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

esto funciona para mí, también ... –

0

Crear una subrutina Perl:

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

y utilizarlo como a continuación:

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

o utilizar Perl aquí-doc para multi-línea de comandos:

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