Eu preciso verificar a existência de uma variável em uma if
declaração. Algo para o efeito de:
if [ -v $somevar ]
then
echo "Variable somevar exists!"
else
echo "Variable somevar does not exist!"
E a pergunta mais próxima disso foi essa , que na verdade não responde à minha pergunta.
$somevar
para um valor / string se a variável não existe:${somevar:=42}
.[ -n "$var" ]
ou[ ! -z "$var" ]
). Eu acho que as verificações de existência / inexistência são muito sutis e eu prefiro meu código grosso e simples.[ -n "$var" ]
? Relacionado: stackoverflow.com/questions/3601515/…Respostas:
No bash moderno (versão 4.2 e superior):
De
help test
:fonte
[ -v name_of_var ]
.$1
,$-
,$#
...test
ou[
; Não está disponível em/usr/bin/test
. Compareman test
comhelp test
.Depende do que você quer dizer com existe .
Será uma variável que foi declarada, mas não atribuído existir ?
Será uma variável de matriz (ou de hash) que foi atribuída uma lista vazia existir ?
Será uma variável que aponta nameref a uma variável que não está actualmente atribuído existir ?
Você considera
$-
,$#
,$1
variáveis? (POSIX não).Nas conchas tipo Bourne, o caminho canônico é:
Que trabalha para variáveis escalares e outros parâmetros de dizer se uma variável tem sido atribuído um valor (vazio ou não, automaticamente, a partir do ambiente, assigments,
read
,for
ou outras).Para os reservatórios que têm um
typeset
oudeclare
comando, que não iria relatar como definir as variáveis que foram declaradas , mas não atribuídos exceto emzsh
.Para shells que suportam matrizes, exceto
yash
ezsh
que não reportariam como variáveis de matriz definidas , a menos que o elemento do índice 0 tenha sido definido.Para
bash
(mas nãoksh93
nemzsh
), para variáveis do tipo matriz associativa , que não as reportariam como definidas, a menos que seu elemento da chave "0" tenha sido definido.Para
ksh93
ebash
, para variáveis do tipo nameref , isso só retornará true se a variável referenciada pelo nameref for considerada configurada .Para
ksh
,zsh
ebash
, uma abordagem potencialmente melhor poderia ser:Para
ksh93
,zsh
ebash
4.4 ou acima, há também:Que reportará variáveis que foram definidas ou declaradas.
fonte
declare -p
/typeset -p
trabalhabash
agora também.bash -c 'typeset -i a; typeset -p a'
e compare comksh93
ouzsh
.Como mencionado na resposta no SO , aqui está uma maneira de verificar:
onde $ {somevar + x} é uma expansão de parâmetro que avalia como nulo se var estiver desativado e substitui a string "x" caso contrário.
O uso
-n
, conforme sugerido pela outra resposta, verificará apenas se a variável contém uma sequência vazia. Não verificará sua existência.fonte
$somevar
para lidarIFS=x
. Ou isso ou citaçãox
.if [ -z "${somevar+x}" ]
? A citação ainda seria necessária dentro[[
e]]
?[ test
rotinas aceitam parâmetros da linha de comando e, portanto, deve-se confiar nas expansões e interpretações usuais, conforme ordenadas da maneira usual, para tornar na invocação do teste aplicado o que você deve fazer com que seja lido por qualquer linha de comando do programa. teste {! + "!"}set -u
estiver em vigor e a versão do Bash for anterior à 4.2.POSIXly:
ou você pode deixar seu shell mostrar a mensagem para você:
fonte
trap
só pode funcionar em EXIT. É tudo o que estou dizendo - simplesmente não se aplica como um passe / falha muito bem. E também não sou eu que falei - já fiz exatamente isso antes e demorou um pouco para comentar sobre isso para me convencer. Então, eu apenas pensei em pagar adiante.fonte
sh
compatível, e é exatamente o que eu preciso.... não imprimirá nada quando não estiver. Ou...
... vou te dizer de qualquer maneira.
você pode usar o valor de retorno de um teste para expandir dinamicamente para a sequência de formato apropriada para sua condição:
Você também pode
printf
falhar com base em uma substituição ...... que imprime
$var does not exist!
em stderr e retorna diferente de 0 quando$var
está desativado, mas imprime$var does exist!
em stdout e retorna 0 quando$var
está definido.fonte
Esta linha simples funciona (e funciona na maioria dos shells POSIX):
Ou, escrito em uma forma mais longa:
A expansão é:
A
${var+"false"}
expansão se expande para "nulo" de "falso".Em seguida, "nothing" ou "false" é executado e o código de saída é definido.
Não há necessidade de chamar o comando
test
([
ou[[
), pois o valor de saída é definido pela (execução) da própria expansão.fonte
$IFS
contém f, a, l, s ou e. Como em outras respostas, há o caso de matrizes, hashes ou outros tipos de variáveis que podemos mencionar.most POSIX shells
.most
significaIn the greatest number of instances
, não todos. ... ... Então, sim, em uma condição obscurawhen $IFS contains f, a, l, s or e
e, para alguma casca obscura,some old versions of zsh
isso falha: que choque! Eu devo assumir que esse bug foi resolvido há muito tempo. ... ... Você está propondo que devemos escrever código para conchas quebradas há muito tempo ?.O caminho da casca pura:
Script de teste:
Resultados:
fonte
Com o bash 4.4.19, o seguinte funcionou para mim. Aqui está um exemplo completo
fonte
Você não pode usar o
if
comando para verificar a existência de variáveis declaradas no bash, no entanto, a-v
opção existe no bash mais recente, mas não é portátil e você não pode usá-lo embash
versões mais antigas. Porque quando você estiver usando uma variável, se ela não existir, ela nascerá ao mesmo tempo.Por exemplo, imagine que eu não usei ou atribui um valor à
MYTEST
variável, mas quando você está usando o comando echo, isso não mostra nada! Ou se você estiver usandoif [ -z $MYTEST ]
, retornou valor zero! Não retornou outro status de saída, o que informa que essa variável não existe!Agora você tem duas soluções (sem
-v
opção):declare
comandoset
comandoPor exemplo:
Infelizmente, esses comandos também mostram funções carregadas na memória! Você pode usar o
declare -p | grep -q MYTEST ; echo $?
comando para obter resultados mais limpos.fonte
Função para verificar se a variável é declarada / não definida
incluindo vazio
$array=()
Além da resposta de @ Gilles
- que eu não encontrar uma maneira para encapsular-lo dentro de uma função - Eu gostaria de adicionar uma versão simples, que é parcialmente baseado em Richard Hansen 's resposta , mas faz endereço também a armadilha que ocorre com um vazio
array=()
:$1
contiver o nome de um vazio$array=()
, a chamada para declarar garantirá o resultado corretoCom o seguinte código, as funções podem ser testadas:
O script deve retornar
fonte
função bash que funciona para os tipos escalar e matriz :
definição
invocação
fonte