uso sentencias scripts script programacion por pasar parametros ejemplos control comillas argumentos bash quoting

bash - sentencias - shell script argumentos



¿Cómo paso los argumentos de script que contienen comillas/espacios? (3)

Estoy tratando de escribir un script de notify-finish que se puede añadir a cualquier comando. Cuando termine, ejecutará el comando dado por los argumentos siguientes, luego enviará un correo electrónico al usuario cuando se complete el comando. Esto es lo que tengo:

PROG=$1 # Run command given by arguments $@ ECODE=$? echo -e "Subject: `hostname`: $PROG finished/r/nTo: <$USER>/r/n/r/nExited with $ECODE/r/n" | sendmail $USER

Esto funciona la mayor parte del tiempo, pero cuando los argumentos contienen espacios, la cita se elimina.

Ejemplo de trabajo:

notify-finished rsync -avz source/ user@remote:dest/

Ejemplo de falla:

notify-finished rsync -avz -e ''ssh -c blowfish'' source/ user@remote:dest/

En el segundo caso, $@ se expande a rsync -avz -e ssh -c blowfish source user@remote:dest/ , faltan las comillas simples. Tampoco funciona con comillas dobles, ni con $* .

Después de leer otras publicaciones, intenté colocar el comando en una matriz, pero tengo el mismo problema:

CMD=(notify-finished rsync -avz -e ''ssh -c blowfish'' source/ user@remote:dest/) ${CMD[@]}

¿Cómo hago este trabajo para todos los argumentos?


Coloque comillas dobles alrededor de las sustituciones de variables para evitar que se analicen (tenga en cuenta que esto se aplica a todas las variables: $@ , $1 y $PROG ). También: no ponga un $ antes de un nombre de variable cuando se le asigne; use # para comentarios; y, en la última línea, las comillas simples evitarán que las variables se sustituyan en absoluto.

PROG="$1" shift # Run program below "$PROG" "$@" ECODE=$? # note: this will always be a number, so it doesn''t have to be protected with double-quotes echo -e "Subject: $(hostname): $PROG finished/r/nTo: <$USER>/r/n/r/nExited with $ECODE/r/n'' | sendmail "$USER"


Tu guión debe ser así:

# Run program below PROG="$@" ${PROG} ECODE=$? echo -e "Subject: $(hostname): ${PROG} finished/r/nTo: <$USER>/r/n/r/nExited with $ECODE/r/n"

El comando final echo necesita comillas dobles en lugar de comillas simples '' para interpretar y expandir $ variables.

Y deberías incluir el argumento de la línea de comando entre comillas dobles así como esto:

notify-finished "rsync -avz -e ''ssh -c blowfish'' source/ user@remote:dest/"


Utilice "$@" con comillas:

prog="$1" "$@" ecode="$?" echo "$prog exited with $ecode"

Esto pasará cada argumento exactamente como fue recibido. Si no incluye las citas, cada elemento se dividirá de acuerdo con $IFS :

  • "$@" es como "$1" "$2" "$3" ... , pasando cada elemento como un argumento separado.
  • "$*" es como "$1 $2 $3 ..." , pasando todos los elementos concatenados como un solo argumento
  • $* y $@ es como $1 $2 $3 ... , dividiendo cada elemento en espacios en blanco, expandiendo todos los globos y pasando cada palabra resultante como un elemento separado ( $IFS ).

Lo mismo ocurre con las matrices, como "${array[@]}" y "${array[*]}"