bash eval

No parece poder usar la opción bash-c con argumentos después de la cadena de la opción-c



eval (4)

La página del hombre para bash dice, con respecto a la opción -c:

-c string
Si la opción -c está presente, los comandos se leen de la string . Si hay argumentos después de la cadena, se asignan a los parámetros posicionales, comenzando con $0 .

Entonces, dada esa descripción, creo que algo así debería funcionar:

bash -c "echo arg 0: $0, arg 1: $1" arg1

pero la salida solo muestra lo siguiente, así que parece que los argumentos después de la cadena -c no están siendo asignados a los parámetros posicionales.

arg 0: -bash, arg 1:

Estoy ejecutando un bash bastante antiguo (en Fedora 4):

[root @ dd42 trunk] # bash --version
GNU bash, versión 3.00.16 (1) - liberación (i386-redhat-linux-gnu)
Copyright (C) 2004 Free Software Foundation, Inc.

Lo que estoy tratando de hacer aquí es ejecutar un poco de script de shell con argumentos. Pensé que "parecía muy prometedor", de ahí el problema anterior. Me preguntaba sobre el uso de eval, pero no creo que pueda pasar args a las cosas que siguen a eval. Estoy abierto a otras sugerencias también.


Agregue una barra diagonal inversa a $0 (es decir, /$0 ), de lo contrario su caparazón actual escapa $0 al nombre del caparazón antes de que llegue a la subshell.


Debe usar comillas simples para evitar que ocurra interpolación en el intérprete de comandos que realiza la llamada.

$ bash -c ''echo arg 0: $0, arg 1: $1'' arg1 arg2 arg 0: arg1, arg 1: arg2

O escape las variables en su cadena de comillas dobles. Cuál usar puede depender exactamente de lo que quiere poner en su fragmento de código.


Debido a que '' $0 '' y '' $1 '' en su cadena se reemplazan con una variable # 0 y # 1, respectivamente.

Tratar :

bash -c "echo arg 0: /$0, arg 1: /$1" arg0 arg1

En este código, $ de los dos son de escape, por lo que la base lo ve como una cadena $ y no se reemplaza.

El resultado de este comando es:

arg 0: arg0, arg 1: arg1

Espero que esto ayude.


Martin tiene razón acerca de la interpolación: necesita usar comillas simples. Pero tenga en cuenta que si intenta pasar argumentos a un comando que se está ejecutando dentro de la cadena, debe reenviarlos explícitamente. Por ejemplo, si tiene un script foo.sh como:

#!/bin/bash echo 0:$0 echo 1:$1 echo 2:$2

Entonces deberías llamarlo así :

$ bash -c ''./foo.sh ${1+"$@"}'' foo "bar baz" 0:./foo.sh 1:bar baz 2:

O más generalmente bash -c ''${0} ${1+"$@"}'' <command> [argument]...

No así :

$ bash -c ./foo.sh foo "bar baz" 0:./foo.sh 1: 2:

Ni así :

$ bash -c ''./foo.sh $@'' foo "bar baz" 0:./foo.sh 1:bar 2:baz

Esto significa que puede pasar argumentos a subprocesos sin incrustarlos en la cadena de comandos, y sin preocuparse por escapar de ellos.