Minha pergunta é sobre os valores de retorno produzidos por este código:
if [ -n ]; then echo "true"; else echo "false"; fi
Isso imprime true
.
Seu teste complementar usando [ -z ]
também imprime true
:
if [ -z ]; then echo "true"; else echo "false"; fi
No código acima, por que o [ -n ]
teste assume o valor da sequência que não é passado, como não nulo?
O código abaixo é impresso false
. Isso é esperado, já que o valor da cadeia passada é nulo e tem tamanho zero.
if [ -n "" ]; then echo "true"; else echo "false"; fi
[ -t ]
foi testar se stdout foi um terminal (curto para[ -t 1 ]
) e algumas conchas ainda estão fazendo isso (no caso deksh93
apenas quando esse-t
é literal), por isso é melhor usar[ -n "$var" ]
do que[ "$var" ]
. Embora isso ainda falhe em algumastest
implementações antigas para valores de$var
like=
, nesse caso[ "" != "$var" ]
ou[ "x$var" != x ]
oucase $x in "")...
pode ser melhor.-o
daqui. Em alguns shellsbash
,-o
é um operador unário (teste se uma opção está configurada) e binário (ou), portanto, coisas como[ ! -o monitor ]
são ambíguas. Está testando se amonitor
opção não está definida ou se são!
oumonitor
não cadeias de caracteres vazias? As regras POSIX decidem: a última (que é diferente com[[ ! -o monitor ]]
).[ -n ]
não usa o-n
teste.O
-n
in[ -n ]
não é um teste. Quando existe apenas um argumento entre[
e]
, esse argumento é uma sequência testada para verificar se está vazia. Mesmo quando essa sequência tem uma liderança-
, ela ainda é interpretada como um operando, não como um teste. Como a cadeia-n
não está vazia - ela contém dois caracteres-
en
, não zero, de caráteres[ -n ]
avaliada como verdadeira.Como diz Ignacio Vazquez-Abrams , onde
string
há um único argumento, o teste realizadostring
em é o mesmo que o realizado por ele . Quando acontece , nada de especial acontece. O in e o segundo in são simplesmente cadeias sendo testadas quanto ao vazio.[ string ]
[ -n string ]
string
-n
-n
[ -n ]
-n
[ -n -n ]
Quando existe apenas um argumento entre
[
e]
, esse argumento é sempre uma string a ser testada para verificar se não há vazio, mesmo que seja nomeado o mesmo que um teste. Da mesma forma, quando há dois argumentos entre[
e]
o primeiro deles-n
, o segundo é sempre uma sequência a ser testada para verificar se não há vazios, mesmo que seja nomeado o mesmo que um teste. Isso ocorre simplesmente porque a sintaxe para[
insiste em que um único argumento entre[
e]
depois-n
é um operando de string.Pelo mesmo motivo que
[ -n ]
não usa o-n
teste,[ -z ]
não usa o-z
teste.Você pode aprender mais sobre
[
abash
examinando a ajuda para ele. Observe que é um shell embutido :Assim, você pode executar
help [
para obter ajuda:Para obter mais informações, incluindo quais testes são suportados e como eles funcionam, você precisará ver a ajuda
test
. Quando você executa o comandohelp test
, você obtém uma lista detalhada. Em vez de reproduzir tudo, aqui está a parte sobre os operadores de string:Observe isso
-n STRING
eSTRING
faça o mesmo: eles testam se a stringSTRING
não está vazia.fonte
IFS
espaços em branco, farão isso; variáveis que contêm várias palavras em vez de zero produzem outro efeito e podem fazer com que um teste completamente diferente seja executado. As strings que aparecem literalmente com a intenção de serem operandos somente funcionarão corretamente se não contiverem espaços ou tabulações ou se estiverem entre aspas. A resposta se tornaria muito mais longa e mais complicada se eu abordasse esse tópico de uma maneira acessível. Se você decidir postar uma resposta, sinta-se à vontade para @ me aqui sobre isso![ "$var" ]
nunca seria útil como teste, pois$var
pode se expandir para-n
.[ -n ]
é verdadeiro porque o[
comando (também conhecido comotest
comando) atua de acordo com o número de argumentos que é fornecido. Se ele receber apenas um único argumento, o resultado será "verdadeiro" se o argumento for uma sequência não vazia. "-n" é uma sequência com 2 caracteres, não está vazia, portanto, "verdadeira".fonte