No Bash, quando você não está preocupado com a portabilidade para shells que não o suportam, você deve sempre usar a sintaxe de colchetes duplos:
Qualquer um dos seguintes:
if [[ -z $variable ]]
if [[ -z "$variable" ]]
if [[ ! $variable ]]
if [[ ! "$variable" ]]
No Bash, usando colchetes duplos, as aspas não são necessárias. Você pode simplificar o teste para uma variável que contém um valor para:
if [[ $variable ]]
Esta sintaxe é compatível com ksh (pelo menos ksh93, de qualquer maneira). Ele não funciona em shells POSIX puros ou Bourne mais antigos, como sh ou dash.
Veja minha resposta aqui e BashFAQ/031 para obter mais informações sobre as diferenças entre colchetes duplos e simples.
Você pode testar para ver se uma variável não está definida especificamente (diferente de uma string vazia):
if [[ -z ${variable+x} ]]
onde o "x" é arbitrário.
Se você quiser saber se uma variável é nula, mas não unset:
Uma variável no bash (e qualquer shell compatível com POSIX) pode estar em um dos três estados:
desarmar
definido para a string vazia
definido como uma string não vazia
Na maioria das vezes, você só precisa saber se uma variável está definida como uma string não vazia, mas ocasionalmente é importante distinguir entre não definida e definida como uma string vazia.
A seguir estão exemplos de como você pode testar as várias possibilidades e funciona no bash ou em qualquer shell compatível com POSIX:
if [ -z "${VAR}" ]; then
echo "VAR is unset or set to the empty string"
fi
if [ -z "${VAR+set}" ]; then
echo "VAR is unset"
fi
if [ -z "${VAR-unset}" ]; then
echo "VAR is set to the empty string"
fi
if [ -n "${VAR}" ]; then
echo "VAR is set to a non-empty string"
fi
if [ -n "${VAR+set}" ]; then
echo "VAR is set, possibly to the empty string"
fi
if [ -n "${VAR-unset}" ]; then
echo "VAR is either unset or set to a non-empty string"
fi
Aqui está a mesma coisa, mas em forma de tabela acessível:
A ${VAR+foo}construção se expande para a string vazia se não estiver definida VARou para foose VARestiver definida para qualquer coisa (incluindo a string vazia).
A ${VAR-foo}construção se expande para o valor de VARif set (incluindo set para a string vazia) e fooif unset. Isso é útil para fornecer padrões substituíveis pelo usuário (por exemplo, ${COLOR-red}diz para usar reda menos que a variável COLORtenha sido definida como algo).
A razão pela qual [ x"${VAR}" = x ]é frequentemente recomendado para testar se uma variável não está definida ou definida para a string vazia é porque algumas implementações do [comando (também conhecido como test) são bugadas. Se VARfor definido como algo como -n, algumas implementações farão a coisa errada quando fornecidas [ "${VAR}" = "" ]porque o primeiro argumento de [é interpretado erroneamente como o -noperador, não como uma string.
Outra opção que usei é definir uma variável, mas pode ser substituída por outra variável, por exemplo
export PORT=${MY_PORT:-5432}
Se a $MY_PORTvariável estiver vazia, PORTserá definida como 5432, caso contrário, PORT será definida como o valor de MY_PORT. Observe que a sintaxe inclui os dois pontos e o traço.
Uma alternativa que vi [ -z "$foo" ]é a seguinte, porém não sei por que as pessoas usam esse método, alguém sabe?
[ "x${foo}" = "x" ]
De qualquer forma, se você estiver desabilitando variáveis não definidas (por set -uou set -o nounset), você terá problemas com ambos os métodos. Há uma correção simples para isso:
A pergunta pergunta como verificar se uma variável é uma string vazia e as melhores respostas já foram dadas para isso.
Mas cheguei aqui depois que um período passou programando em php e o que eu estava realmente procurando era uma verificação como a função vazia em php trabalhando em um shell bash.
Depois de ler as respostas, percebi que não estava pensando corretamente no bash, mas de qualquer forma, naquele momento, uma função como empty in php teria sido muito útil no meu código bash.
Como acho que isso pode acontecer com outras pessoas, resolvi converter a função vazia do php em bash
De acordo com o manual do php : uma variável é considerada vazia se não existir ou se seu valor for um dos seguintes:
"" (uma string vazia)
0 (0 como um número inteiro)
0,0 (0 como um float)
"0" (0 como uma string)
uma matriz vazia
uma variável declarada, mas sem um valor
É claro que os casos nulo e falso não podem ser convertidos em bash, então eles são omitidos.
function empty
{
local var="$1"
# Return true if:
# 1. var is a null string ("" as empty string)
# 2. a non set variable is passed
# 3. a declared variable or array but without a value is passed
# 4. an empty array is passed
if test -z "$var"
then
[[ $( echo "1" ) ]]
return
# Return true if var is zero (0 as an integer or "0" as a string)
elif [ "$var" == 0 2> /dev/null ]
then
[[ $( echo "1" ) ]]
return
# Return true if var is 0.0 (0 as a float)
elif [ "$var" == 0.0 2> /dev/null ]
then
[[ $( echo "1" ) ]]
return
fi
[[ $( echo "" ) ]]
}
Exemplo de uso:
if empty "${var}"
then
echo "empty"
else
echo "not empty"
fi
Demonstração:
o seguinte trecho:
#!/bin/bash
vars=(
""
0
0.0
"0"
1
"string"
" "
)
for (( i=0; i<${#vars[@]}; i++ ))
do
var="${vars[$i]}"
if empty "${var}"
then
what="empty"
else
what="not empty"
fi
echo "VAR \"$var\" is $what"
done
exit
saídas:
VAR "" is empty
VAR "0" is empty
VAR "0.0" is empty
VAR "0" is empty
VAR "1" is not empty
VAR "string" is not empty
VAR " " is not empty
Tendo dito que em uma lógica bash as verificações em zero nesta função podem causar problemas colaterais imho, qualquer pessoa que use esta função deve avaliar esse risco e talvez decidir cortar essas verificações deixando apenas a primeira.
Meus 5 centavos: também existe uma sintaxe mais curta que if ..., esta:
VALUE="${1?"Usage: $0 value"}"
Esta linha definirá VALUE se um argumento tiver sido fornecido e imprimirá uma mensagem de erro prefixada com o número da linha do script em caso de erro (e encerrará a execução do script).
Outro exemplo pode ser encontrado no guia abs (procure por «Exemplo 10-7»).
Isso retornará true se uma variável não estiver definida ou definida para a string vazia ("").
No Bash, quando você não está preocupado com a portabilidade para shells que não o suportam, você deve sempre usar a sintaxe de colchetes duplos:
Qualquer um dos seguintes:
No Bash, usando colchetes duplos, as aspas não são necessárias. Você pode simplificar o teste para uma variável que contém um valor para:
Esta sintaxe é compatível com ksh (pelo menos ksh93, de qualquer maneira). Ele não funciona em shells POSIX puros ou Bourne mais antigos, como sh ou dash.
Veja minha resposta aqui e BashFAQ/031 para obter mais informações sobre as diferenças entre colchetes duplos e simples.
Você pode testar para ver se uma variável não está definida especificamente (diferente de uma string vazia):
onde o "x" é arbitrário.
Se você quiser saber se uma variável é nula, mas não unset:
Uma variável no bash (e qualquer shell compatível com POSIX) pode estar em um dos três estados:
Na maioria das vezes, você só precisa saber se uma variável está definida como uma string não vazia, mas ocasionalmente é importante distinguir entre não definida e definida como uma string vazia.
A seguir estão exemplos de como você pode testar as várias possibilidades e funciona no bash ou em qualquer shell compatível com POSIX:
Aqui está a mesma coisa, mas em forma de tabela acessível:
A
${VAR+foo}
construção se expande para a string vazia se não estiver definidaVAR
ou parafoo
seVAR
estiver definida para qualquer coisa (incluindo a string vazia).A
${VAR-foo}
construção se expande para o valor deVAR
if set (incluindo set para a string vazia) efoo
if unset. Isso é útil para fornecer padrões substituíveis pelo usuário (por exemplo,${COLOR-red}
diz para usarred
a menos que a variávelCOLOR
tenha sido definida como algo).A razão pela qual
[ x"${VAR}" = x ]
é frequentemente recomendado para testar se uma variável não está definida ou definida para a string vazia é porque algumas implementações do[
comando (também conhecido comotest
) são bugadas. SeVAR
for definido como algo como-n
, algumas implementações farão a coisa errada quando fornecidas[ "${VAR}" = "" ]
porque o primeiro argumento de[
é interpretado erroneamente como o-n
operador, não como uma string.-z
é a melhor maneira.Outra opção que usei é definir uma variável, mas pode ser substituída por outra variável, por exemplo
Se a
$MY_PORT
variável estiver vazia,PORT
será definida como 5432, caso contrário, PORT será definida como o valor deMY_PORT
. Observe que a sintaxe inclui os dois pontos e o traço.Se você estiver interessado em distinguir os casos de status set-empty versus unset, veja a opção -u para bash:
Uma alternativa que vi
[ -z "$foo" ]
é a seguinte, porém não sei por que as pessoas usam esse método, alguém sabe?De qualquer forma, se você estiver desabilitando variáveis não definidas (por
set -u
ouset -o nounset
), você terá problemas com ambos os métodos. Há uma correção simples para isso:Nota: isso deixará sua variável indef.
A pergunta pergunta como verificar se uma variável é uma string vazia e as melhores respostas já foram dadas para isso.
Mas cheguei aqui depois que um período passou programando em php e o que eu estava realmente procurando era uma verificação como a função vazia em php trabalhando em um shell bash.
Depois de ler as respostas, percebi que não estava pensando corretamente no bash, mas de qualquer forma, naquele momento, uma função como empty in php teria sido muito útil no meu código bash.
Como acho que isso pode acontecer com outras pessoas, resolvi converter a função vazia do php em bash
De acordo com o manual do php :
uma variável é considerada vazia se não existir ou se seu valor for um dos seguintes:
É claro que os casos nulo e falso não podem ser convertidos em bash, então eles são omitidos.
Exemplo de uso:
Demonstração:
o seguinte trecho:
saídas:
Tendo dito que em uma lógica bash as verificações em zero nesta função podem causar problemas colaterais imho, qualquer pessoa que use esta função deve avaliar esse risco e talvez decidir cortar essas verificações deixando apenas a primeira.
todo o if-then e -z são desnecessários.
Pessoalmente, prefiro uma maneira mais clara de verificar:
Meus 5 centavos: também existe uma sintaxe mais curta que
if ...
, esta:Esta linha definirá VALUE se um argumento tiver sido fornecido e imprimirá uma mensagem de erro prefixada com o número da linha do script em caso de erro (e encerrará a execução do script).
Outro exemplo pode ser encontrado no guia abs (procure por «Exemplo 10-7»).