O teste de existência de arquivo bash é sempre verdadeiro

3

Eu tenho as seguintes linhas do script bash para testar se existe um arquivo:

MYAPPPATH=$(find $APPDIR -iname myapp* -print)
if [ -e $MYAPPPATH ]
then
    echo "File exists" 
fi

No entanto, quando o arquivo que inicia com "myapp" não existe, portanto, MYAPPPATH = '', a verificação acima é bem-sucedida novamente. Veja o que acontece ao usar set -x e o arquivo não existe:

++ find /path/to/app -iname 'myapp*' -print
+ MYAPPPATH=
+ '[' -e ']'
+ echo 'File exists'

Qual é o motivo disso?

O que preciso fazer para que isso funcione como esperado?

    
por trikelef 20.11.2014 / 11:35

3 respostas

10

Quando sua variável está vazia, seu comando se torna:

[ -e ]

Nesse caso, você chama [..] com um argumento -e . A string "-e" não é nula, portanto, test retorna true.

Esse comportamento é definido pelo teste POSIX :

In the following list, $1, $2, $3, and $4 represent the arguments presented to test:

0 arguments:

Exit false (1).

1 argument:

Exit true (0) if $1 is not null; otherwise, exit false.

....

Para que funcione, você deve aspas duplas sua variável :

[ -e "$MYAPPPATH" ]

Isso funciona porque -e com um argumento que é uma string vazia é falso.

    
por 20.11.2014 / 11:44
4

Acostume-se a cotar variáveis. Sempre os cite; que evita erros de avaliação quando é necessário:

if [ -e "$MYAPPPATH" ]

Isso não teria acontecido com o comando composto específico bash:

if [[ -e $MYAPPPATH ]]
    
por 20.11.2014 / 11:41
1

Existem algumas outras maneiras:

  1. Verifique a variável antes (com edições de acordo com comentários)

    if [ -n "$MYAPPPATH" ] && [ -e "$MYAPPPATH" ] ; then ...
    
  2. Use locate * em vez de find

    if locate -w "$APPDIR/myapp*" ; then ...
    

* 1 Para usar locate , não se esqueça de atualizar o banco de dados de arquivos por updatedb

    
por 20.11.2014 / 11:54