Estoy tratando de aprender a usar getopts para poder tener scripts con entrada analizada (aunque creo que getopts podría ser mejor). Estoy tratando de escribir un script simple para devolver porcentajes de uso de la partición. El problema es que a una de mis funciones bash no parece gustarle que haga referencia $1como una variable dentro de la función. La razón por la que hago referencia $1es porque a la get_percentfunción se le puede pasar un punto de montaje como un argumento opcional para mostrar en lugar de todos los puntos de montaje.
La secuencia de comandos
#!/usr/bin/bash
set -e
set -u
set -o pipefail
get_percent(){
if [ -n "$1" ]
then
df -h $1 | tail -n +2 | awk '{ print $1,"\t",$5 }'
else
df -h | tail -n +2 | awk '{ print $1,"\t",$5 }'
fi
}
usage(){
echo "script usage: $(basename $0) [-h] [-p] [-m mount_point]" >&2
}
# If the user doesn't supply any arguments, we run the script as normal
if [ $# -eq 0 ];
then
get_percent
exit 0
fi
# ...
La salida
$ bash thing.sh
thing.sh: line 8: $1: unbound variable
$ bash -x thing.sh
+ set -e
+ set -u
+ set -o pipefail
+ '[' 0 -eq 0 ']'
+ get_percent
thing.sh: line 8: $1: unbound variable
bash
shell-script
scripting
Timothy Pulliam
fuente
fuente

getopts, ¿verdad? Su script se cierra debido a-uantes de llamargetopts.Respuestas:
set -uabortará exactamente como lo describe si hace referencia a una variable que no se ha establecido. Invoca su script sin argumentos, por lo queget_percentse invoca sin argumentos, lo$1que hace que se desarme.Verifique esto antes de invocar su función, o use expansiones predeterminadas (
${1-default}se expandirá adefaultsi no está configurado en otra cosa).fuente
[ -n "${1-}" ](es decir, con un valor predeterminado vacío) para ver si el parámetro está configurado y no está vacío; o[ "${1+x}" = x ]para ver si está configurado, incluso si está vacío.if [[ -n ${1-default} ]]Este es el efecto de
set -u.Puede verificar
$#dentro de la función y evitar hacer referencia$1si no está configurada.Con
$#usted puede acceder a la cantidad de parámetros. En el contexto global es el número de parámetros para el script, en una función es el número de parámetros para la función.En el contexto de la pregunta, es
Tenga en cuenta que debe usar
[ $# -ge 1 ] && [ -n "$1" ]y no[ $# -ge 1 -a -n "$1" ], porque eso primero evaluaría$1y luego comprobaría$#.fuente
Como es
bashasí, puede eludir la verificación para$1establecerlo y simplemente usarlo"$@"($1es el primer parámetro,$@son todos; cuando se cita doblemente, desaparece por completo si no tiene valores, lo que evita que sea atrapadoset -u):También he ajustado ligeramente el resto de la línea para que no obtenga {space} {tab} {space} entre los dos valores que genera, pero inserte solo obtenga una {tab}. Si realmente quiere los dos espacios invisibles, cambie el
awkusoprintf "%s \t %s\n", $1, $5.fuente
$@por ti