2011-08-08 18 views
5

siguiente comandoLinux/Bash: ¿Cómo anular la cita?

echo 'a b' 'c' 

salidas

a b c 

pero los siguientes

X="'a b' 'c'" 
echo $X; 

se outout

'a b' 'c' 

Estoy buscando una manera de unquote $ X, para que salga "a b c", pero sin perder el argumento 'a b' fusionado. (= 2 argumentos en lugar de 3, no hace ninguna diferencia para el comando de 'eco', pero para otros comandos como 'cp')

+2

echo $ {X // \ '/}; // a b c –

Respuesta

7

xargs Proveedores:

$ echo $x 
'a b' 'c' 

$ echo $x | xargs ./echo 
argc = 3 
argv[0] = ./echo 
argv[1] = a b 
argv[2] = c 
+0

Nota: xargs no puede devolver el estado de salida del proceso. Cualquier error 1-125 se mostrará como 123. (Probablemente no haya ninguna solución disponible) Probablemente usaré eval en su lugar, para poder usar el código de salida –

0

Ésta es peluda, me gustaría recomendar trabajando alrededor el problema y no concatenar "ab" y "c" en primer lugar.

7
eval echo $x 

esto pasará a b como primer argumento y c como el segundo

Nota: esto va a evaluar los argumentos, por ejemplo:

$ x='$((3+5))' 
$ eval echo $x 
8 

Si eso no es lo que desea utilizar @ de Vanza xargs.

+0

Gracias. Todavía no he usado "eval", pero parece que xargs es más seguro de acuerdo con las secuencias de comandos de las inyecciones. –

0
X="'a b' 'c'" 
echo $X 
eval "echo $X" 

Cuando se utiliza este código usted tiene que tener cuidado si X posiblemente puede contener caracteres especiales como \"$ o invertidas.

0

¿Estás seguro de que echo recibe un 2 parámetros en echo $X? Para mí, recibe 3. Permite tratar:

X="'a b' 'c'" 
function f(){ echo $#; echo $1; echo $2; echo $3; } 
f $X 

muestra:

3 
'a 
b' 
'c' 

Los 3 parámetros son 'a, b' y 'c'. No creo que sea lo que esperas.

Si usted quiere construir una variable de parámetros múltiples, establezca IFS a un char no usará (tal vez |), y utilizarlo como un delimitador de parámetro en la variable:

X="a b|c" 
IFS="|" 
function f(){ echo $#; echo $1; echo $2; } 
f $X 
1

Por lo general, si está tratando de almacenar múltiples 'palabras' en una sola variable, el método recomendado es no utilizar comillas incrustadas, sino utilizar una matriz:

X=('a b' 'c') 
printf "%s\n" "${X[@]}" 

impresiones:

a b 
c 
0

También es posible combinar xargs y sh -c 'cmd' _ arg1 arg2 ... para volver a analizar los argumentos en la matriz de parámetros posicionales [email protected].

Asignación de la salida a una variable y la reorientación de otra cosa que el estado de salida $? del último proceso de stderr, por ejemplo, hace que sea posible almacenar el código de salida del último proceso en una variable y usarlo después de xargs ha terminado ejecución.

X="'a b' 'c'" 

ret="$(
export IFS='' 
set -o pipefail 
echo $X | xargs sh -c ' 
    for file in "[email protected]"; do 
     echo cp "$file" destdir 1>&2 || { echo $?; kill -HUP $PPID; exit $?; } 
     #(exit 3) || { echo $?; kill -HUP $PPID; exit $?; } 
     #(exit 3) || { echo $?; kill -HUP $PPID; kill -HUP -- -$$; } 
    done 
    echo $? 
' _ 
echo $? '|' ${PIPESTATUS[@]} 1>&2 
)" 
echo "$ret" | tail -1 
0

No utilice eval para algo como esto. set mantendrá la integridad de los parámetros y los comandos que no sean echo jugarán muy bien con ellos. Solo tenga en cuenta que perderá la (s) referencia (s) a cualquier parámetro posicional actual.

set -- "a b" "c" 
echo "[email protected]" 
#a b c 
echo $1 
#a b 
echo $2 
#c