como verificar se $ 1 e $ 2 são nulos?


40

Estou executando algum script que passa o argumento string e quero fazer a declaração if else mostrada abaixo:

if [ $1 != '' ] && [ $2 != '' ]
then 
    do something.....

mas mostrou Error too many argument. Por quê?


Você deve fornecer 1. o comando que você chama de script e 2. a saída completa.
— Lucio

2
Você deveria usar [[ ]]. Caso contrário, você deve citar suas variáveis.
— Christophe De Troyer

Se $ 1 não existisse, então $ 2 se tornaria $ 1, o que faz com que o teste de $ 1 e $ 2 sendo nulo pareça irrelevante.
— WinEunuuchs2Unix

@ WinEunuuchs2Unix Não necessariamente irrelevante - em alguns casos, você deseja garantir que haja realmente algo em vez de cadeia em branco ou nula nos argumentos. $1pode estar desconfigurado ou configurado como string nula pelo usuário do script. Considere esta seqüência de comandos: $ set '' bardepois echo "x${1}x";Ambas as variáveis são definidas, mas um deles é nulo.
— Sergiy Kolodyazhnyy

Respostas:


55

Tente usar o teste -z:

if [ -z "$1" ] && [ -z "$2" ]

Do homem bash:

-z string
   True if the length of string is zero.

Funciona para mim!
— pengisgood

é interessante que a resposta mais votada e aceita realmente não responda à pergunta.
— mehmet

Ao escrever scripts de shell portáteis, esse sinalizador deve ser usado com cuidado, pois em certos Unixes comerciais, esse sinalizador está com defeito. Veja minha resposta para fontes vinculadas.
— Sergiy Kolodyazhnyy

14

Como isso está marcado bash, eu recomendo que você use a construção de teste estendida ( [[...]]) e esqueça as aspas:

if [[ -z $1 && -z $2 ]]; then
...

A menos que você esteja shbuscando compatibilidade com / POSIX, não há motivo para não usá-lo [[ ]].


3

O seguinte também funciona,

if [ "$1" == "" && "$2" == ""]; then
    echo NULL
fi

O &&e outros separadores de comandos lógicos não são permitidos no clássico test. Você tem que usar outras construções de teste em vez (como -a, eu acho)
— Muru

3

Para a versão antiga da resposta, consulte a segunda parte desta resposta. Se você quiser saber detalhes, continue lendo

A causa do problema

Na própria pergunta, é relatado que o OP vê too many arguments error, o que, quando testado bash, não parece ser o caso:

$ [ $1 != '' ] && [ $2 != '' ]
bash: [: !=: unary operator expected

Com o /bin/shqual está realmente vinculado ao /bin/dashUbuntu, o erro relatado da seguinte maneira:

$ sh
$ [ $1 != '' ] && [ $2 != '' ]
sh: 1: [: !=: unexpected operator

E o autônomo /bin/testtambém:

$ /usr/bin/test $1 != ''  
/usr/bin/test: missing argument after ‘’

Sidenote: Se você está se perguntando o que é /usr/bin/teste porque eu estou usando bashe sh, em seguida, você deve saber que [é alias para testo comando, que também existe como executável autônomo ou mais comumente - como shell built-in que é o que cada shell usará primeiro . Quanto às ifinstruções, elas operam nas estátuas de saída dos comandos, daí o motivo [e testsão comandos, com tudo o mais sendo argumentos para esses comandos - a ordem incorreta desses argumentos da linha de comando leva a erros.

Voltar ao tópico: não está claro como o OP recebeu o erro não relacionado. No entanto, nos três casos, o problema é o mesmo - a variável não definida será tratada como vazia, portanto, o que o shell vê com essas variáveis ​​não citadas é

[ != '' ]

que quebra a sintaxe que testentende. Lembra do que eu disse sobre a ordem imprópria dos argumentos da linha de comando? Por isso, é importante citar. Vamos ativar a saída de diagnóstico e ver o que o shell executa:

$ set -x
# throws error
$ [ $1 != '' ] && [ $2 != '' ] 
+ '[' '!=' '' ']'
bash: [: !=: unary operator expected
# no error
$ [ "$1" != '' ] && [ "$2" != '' ] || echo null vars
+ '[' '' '!=' '' ']'
+ echo null vars
null vars

Melhor maneira de testar variáveis ​​não definidas

Uma abordagem muito frequente que você vê ao redor é a seguinte:

 if [ "x$var1" == "x"  ] && [ "x$var2" == "x"  ];                                                                
 then
     echo "both variables are null"
 fi

Para citar Gilles :

Em ["x $ 1" = "x"], o prefixo x garante que x "$ 1" não possa se parecer com um operador e, portanto, a única maneira pela qual o shell pode analisar esse teste é tratando = como um operador binário.

Presumivelmente, isso deve ser bastante portátil, já que eu os vi em /bin/shscripts. Também pode ser combinado como em

if [ "x${var1}${var2}" == "x" ]; then
    ...
fi

É claro que poderíamos usar a -zbandeira, no entanto, de acordo com pesquisas em algumas conchas, particularmente o ksh88 (de acordo com Stephane Chazelas ), essa bandeira está com defeito.

Veja também


+1 para uma abordagem muito interessante.
— WinEunuuchs2Unix

@ WinEunuuchs2Unix Editado para torná-lo ainda mais interessante :) #
— Sergiy Kolodyazhnyy

1

Acho que o título da postagem não é exato, pois a intenção da mensagem era verificar se $ 1 e $ 2 não são nulos. O exemplo dado estava faltando aspas duplas em $ 1 e $ 2 para funcionar. As variáveis ​​devem ser aspas duplas para serem expandidas ao comparar cadeias. Mas, verificar se $ 1 e $ 2 existem é o mesmo que verificar se $ 2 existem, pois não pode existir se $ 1 não existir. O comando 'if' também não é necessário neste caso, pois 'test' retorna true / false e usa '&&' como 'then' se return for 0 / true:

[ "$2" != '' ] && commands...

Mais simples, com -n (diferente de zero):

[ -n "$2" ] && commands...

Para "verificar se $ 1 e $ 2 são nulos" seria o mesmo que verificar se não há parâmetro:

[ $# -eq 0 ] && commands...
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.