it-swarm-pt.tech

Como determinar se uma variável bash está vazia?

Qual é a melhor maneira de determinar se uma variável no bash está vazia ("")?

Ouvi dizer que é recomendável que eu faça if [ "x$variable" = "x" ]

Essa é a maneira correta? (deve haver algo mais direto)

784
Brent

Isso retornará true se uma variável estiver desconfigurada ou definida como a sequência vazia ("").

if [ -z "$VAR" ];
1075
duffbeer703

No Bash, quando você não está preocupado com a portabilidade para shells que não o suportam, você sempre deve usar a sintaxe entre colchetes:

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 ]]

Essa sintaxe é compatível com ksh (pelo menos ksh93, de qualquer maneira). Ele não funciona em shell Bourne puros POSIX ou mais antigos, como sh ou dash.

Consulte minha resposta aqui e BashFAQ/031 para obter mais informações sobre as diferenças entre colchetes duplos e únicos.

Você pode testar para ver se uma variável está especificamente desconfigurada (diferente de uma sequência vazia):

if [[ -z ${variable+x} ]]

onde o "x" é arbitrário.

Se você deseja saber se uma variável é nula, mas não está desmarcada:

if [[ -z $variable && ${variable+x} ]]
253

Uma variável no bash (e qualquer Shell compatível com POSIX) pode estar em um dos três estados:

  • incerto
  • definido para a sequência vazia
  • definido como uma sequência não vazia

Na maioria das vezes, você só precisa saber se uma variável está definida como uma sequência não vazia, mas, ocasionalmente, é importante distinguir entre a definição não definida e a definida como uma sequência vazia.

A seguir, exemplos de como você pode testar as várias possibilidades, e ele 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 útil:

                        +-------+-------+-----------+
                VAR is: | unset | empty | non-empty |
+-----------------------+-------+-------+-----------+
| [ -z "${VAR}" ]       | true  | true  | false     |
| [ -z "${VAR+set}" ]   | true  | false | false     |
| [ -z "${VAR-unset}" ] | false | true  | false     |
| [ -n "${VAR}" ]       | false | false | true      |
| [ -n "${VAR+set}" ]   | false | true  | true      |
| [ -n "${VAR-unset}" ] | true  | false | true      |
+-----------------------+-------+-------+-----------+

O ${VAR+foo} constrói se expande para a cadeia vazia se VAR estiver desativado ou para foo se VAR estiver definido como qualquer coisa (incluindo a cadeia vazia).

O ${VAR-foo} constrói se expande para o valor de VAR se definido (incluindo definido como a cadeia vazia) e foo se não estiver definido. Isso é útil para fornecer padrões substituíveis pelo usuário (por exemplo, ${COLOR-red} diz para usar red, a menos que a variável COLOR tenha sido definida como algo).

A razão porque [ x"${VAR}" = x ] é frequentemente recomendado para testar se uma variável está desabilitada ou definida como uma sequência vazia, porque algumas implementações do [ comando (também conhecido como test) são bugs. Se VAR estiver definido como algo como -n, algumas implementações farão a coisa errada quando receberem [ "${VAR}" = "" ] porque o primeiro argumento para [ é erroneamente interpretado como o -n operador, não uma sequência.

239
Richard Hansen

-z é a melhor maneira.

Outras opções que usei é definir uma variável, mas ela pode ser substituída por outra variável, por exemplo

export PORT=${MY_PORT:-5432}

Se o $MY_PORT variável está vazia, então PORT é definido como 5432, caso contrário, PORT é definido como o valor de MY_PORT. Observe que a sintaxe inclui dois pontos e traço.

38
Rory

Se você estiver interessado em distinguir os casos de status definido como vazio e status não definido, consulte a opção -u para bash:

$ set -u
$ echo $BAR
bash: BAR: unbound variable
$ [ -z "$BAR" ] && echo true
bash: BAR: unbound variable
$ BAR=""
$ echo $BAR

$ [ -z "$BAR" ] && echo true
true
24
MikeyB

Uma alternativa que eu já vi [ -z "$foo" ] é o seguinte, no entanto, não sei por que as pessoas usam esse método, alguém sabe?

[ "x${foo}" = "x" ]

De qualquer forma, se você não permitir variáveis ​​não definidas (por set -u ou set -o nounset), então você terá problemas com ambos os métodos. Há uma correção simples para isso:

[ -z "${foo:-}" ]

Nota: isso deixará sua variável undef.

8
errant.info

A questão pergunta como verificar se uma variável é uma sequência vazia e as melhores respostas já são dadas para isso.
Mas cheguei aqui depois de um período passado na programação em php e o que eu estava procurando era uma verificação como a função vazia no 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 vazia no php teria sido muito útil no meu código do bash.
Como acho que isso pode acontecer com outras pessoas, decidi converter a função php empty no 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 sequência vazia)
  • 0 (0 as an integer)
  • 0,0 (0 como um flutuador)
  • "0" (0 como uma sequência)
  • uma matriz vazia
  • uma variável declarada, mas sem um valor

É claro que os casos null e false não podem ser convertidos no bash, portanto, 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



Demo:
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

Dito isso, em uma lógica do bash, as verificações com zero nessa função podem causar problemas colaterais, qualquer pessoa que use esta função deve avaliar esse risco e talvez decidir cortá-las, deixando apenas a primeira. .

6
Luca Borrione

Meus 5 centavos: também há uma sintaxe mais curta que if ..., este:

VALUE="${1?"Usage: $0 value"}"

Essa linha definirá VALUE se um argumento tiver sido fornecido e imprimirá uma mensagem de erro anexada com o número da linha de script em caso de erro (e encerrará a execução do script).

Outro exemplo pode ser encontrado em abs-guide (pesquise "Exemplo 10-7").

5
gluk47

todo o if-then e -z são desnecessários.

 ["$ foo"] && echo "foo não está vazio" 
 ["$ foo"] || eco "foo está realmente vazio" 
5
namewithoutwords

Isso é verdade exatamente quando $ FOO está definido e vazio:

[ "${FOO+x}" = x ] && [ -z "$FOO" ]
4
JHS

extensão oneliner da solução de duffbeer7 :

#! /bin/bash
[ -z "$1" ] || some_command_that_needs_$1_parameter
4
andrej

Pessoalmente, prefira uma maneira mais clara de verificar:

if [ "${VARIABLE}" == "" ]; then
  echo VARIABLE is empty
else
  echo VARIABLE is not empty
fi
4
Fedir RYKHTIK

Não é uma resposta exata, mas ocorreu esse truque. Se a string que você procura vem de "um comando", você pode realmente armazená-lo em um ambiente. variável e, em seguida, execute-a sempre para a instrução if, então nenhum colchete é necessário!

Por exemplo, este comando, que determina se você está no debian:

grep debian /proc/version

exemplo completo:

IS_DEBIAN="grep -i debian /proc/version"

if $IS_DEBIAN; then
  echo 'yes debian'
else
  echo 'non debian'
fi

Portanto, é como uma maneira indireta (reexecutá-la sempre) para verificar se há uma sequência vazia (verifica-se a resposta a um erro do comando, mas também retorna uma sequência vazia).

0
rogerdpack