Pasé la última hora tratando de escribir un script bash bastante simple y nunca me sentí tan tonto.
Entonces tengo una lista de cadenas (que son especificaciones de selección de paquetes para un administrador de paquetes, si eso importa) que pueden contener asteriscos. Necesito crear una línea de comando que preserve esos asteriscos y luego llamar a un programa. Aquí está mi ingenuo intento:
xs="foo/bar */*"
xs_cmd=""
for x in $xs; do
xs_cmd="$xs_cmd -0 $x "
done
echo $xs_cmd
Necesito que la echo
llamada sea equivalente a
echo -0 foo/bar -0 '*/*'
que salidas -0 foo/bar -0 */*
.
PD: En realidad, la primera línea es un poco más compleja: xs="$some foo/bar */* $(get_others)"
.
Si ejecuta este script en un directorio que contiene a/b
, obtendrá -0 foo/bar -0 a/b
en su lugar.
Cuando cambio la última línea a
echo "$xs_cmd" # note the quotes
Me sale -0 foo/bar -0 a/b
y primero que nada eso no es lo que quiero, ya que ahora estoy invocando echo
con unsolteroargumento, y además eso me dice que la expansión está ocurriendo antes, probablemente en el for
bucle.
Pero no puedo cambiar la for
línea porque
for x in "$xs"; do # note the quotes
simplemente hará que el bucle se repita solo una vez: -0 foo/bar */*
(hay un único -0
), por lo que agregar esas comillas no es una opción con seguridad.
Ahora, si vuelvo al script original y reemplazo la primera línea con
xs="foo/bar '*/*'" # note additional single quotes
Entiendo -0 foo/bar -0 '*/*'
(las comillas simples no deberían estar ahí).
Parece que probé todas las combinaciones de comillas y barras invertidas de asteriscos y literalmente no tengo idea de qué hacer ahora.
Respuesta1
Utilicé su script original, pero con comillas simples en la primera línea (solo) y funcionó como creo que lo desea ( -0
antes de cada ruta de archivo): -
xs='foo/bar */*'
xs_cmd=""
for x in $xs; do
xs_cmd="$xs_cmd -0 $x "
done
echo $xs_cmd
Probablemente encontrará problemas cuando lo utilice si hay espacios en blanco incrustados en cualquiera de las rutas de archivo. Si es así, cambie el comando en el bucle a: -
xs_cmd="$xs_cmd -0 \"$x\" "
Respuesta2
Dependiendo de lo que esté tratando de lograr, deberá citar estos */*
:
xs="foo/bar '*/*'" #!
xs_cmd=""
for x in $xs ; do
xs_cmd="$xs_cmd -0 $x "
done
echo $xs_cmd
eval echo $xs_cmd
eval "echo $xs_cmd"
o usar matrices, o ambas:
xs=("foo/bar" "*/*") #!
xs_cmd=""
for x in "${xs[@]}"; do
xs_cmd="$xs_cmd -0 '$x' " #!
done
echo "$xs_cmd"
eval "echo $xs_cmd"