Estou tentando aprender como usar getopts para que eu possa ter scripts com entrada analisada (embora eu ache que as getopts poderiam ser melhores). Estou tentando apenas escrever um script simples para retornar porcentagens de uso da partição. O problema é que uma das minhas funções do bash não parece gostar da referência $1
como uma variável dentro da função. A razão de eu referenciar $1
é porque a get_percent
função pode receber um ponto de montagem como um argumento opcional a ser exibido em vez de todos os pontos de montagem.
O script
#!/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
# ...
A saída
$ 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
fonte
fonte
getopts
, não é? Seu script é encerrado-u
antes de ligargetopts
.Respostas:
set -u
será cancelado exatamente como você descreve se fizer referência a uma variável que não foi definida. Você está invocando seu script sem argumentos, portanto,get_percent
está sendo invocado sem argumentos, fazendo$1
com que seja desabilitado.Verifique isso antes de chamar sua função ou use expansões padrão (
${1-default}
será expandido paradefault
se ainda não estiver definido para outra coisa).fonte
[ -n "${1-}" ]
(ou seja, com um valor padrão vazio) para verificar se o parâmetro está definido e não vazio; ou[ "${1+x}" = x ]
para ver se está definido, mesmo que vazio.if [[ -n ${1-default} ]]
Este é o efeito de
set -u
.Você pode verificar
$#
dentro da função e evitar referências$1
se não estiver definido.Com
$#
você pode acessar o número de parâmetros. No contexto global, é o número de parâmetros para o script, em uma função é o número de parâmetros para a função.No contexto da questão, é
Observe que você precisa usar
[ $# -ge 1 ] && [ -n "$1" ]
e não[ $# -ge 1 -a -n "$1" ]
, porque isso primeiro avaliaria$1
e depois verificava$#
.fonte
Como é
bash
possível contornar a verificação para$1
definir e usar"$@"
($1
é o primeiro parâmetro,$@
são todos eles; quando aspas duplas, desaparece completamente se não tiver valores, o que evita que ela seja capturadaset -u
):Também ajustei o restante da linha levemente para que você não tenha {space} {tab} {space} entre os dois valores que você produz, mas insira que você tenha apenas uma {tab}. Se você realmente deseja os dois espaços invisíveis, altere
awk
para usarprintf "%s \t %s\n", $1, $5
.fonte
$@
sobre você