Teste várias condições de arquivos combinando bandeiras - isso funciona?

3

Minha resposta no StackOverflow, que recebeu pelo menos dois votos positivos, foi o que funcionou no shell de uma estação de trabalho I usado no meu local de trabalho anterior. Nessa estação de trabalho, que provavelmente é uma versão antiga do SunOS ou Red Hat Enterprise Linux ou Red Hat Enterprise Linux, [[ -fwd path ]] testa a existência de path como um arquivo regular e um diretório gravável. sh , bash , csh , tcsh e zsh foram os únicos shells possíveis instalados nessa estação de trabalho e, provavelmente, eu o executei em bash .

Estou fazendo essa pergunta porque não consegui reproduzir isso agora em outros sistemas operacionais semelhantes a Unix. Ele sempre me dá um erro de sintaxe , então estou começando a duvidar se já o executei com sucesso.

A minha pergunta é: em que sistemas este código é válido e, em caso afirmativo, este é um bug ou uma característica?

    
por Gao 26.12.2017 / 21:26

1 resposta

3

Não, isso não funciona. Não é realmente em qualquer versão do bash.

Este teste funciona em qualquer versão bash (na verdade, em qualquer shell):

$ [ -fwd ] && echo "It worked" || echo "not"
It worked

Mas o que está sendo testado não é um sinalizador de arquivo, ele está testando se a string -fwd tem comprimento 0 ou não. Como tem alguns personagens, o teste é verdadeiro.

Usando [[ alterar quais flags são permitidos:

$ [[ -fwd  ]] && echo "It worked" || echo "not"
b204sh          : /home/user/so: line 3: unexpected argument to conditional unary operator

Dá o erro acima em bash up to bash 3.2.
Não há erro para versões bash após 3.2, mas o resultado é verdadeiro:

$ [[ -fwd ]] && echo "It worked" || echo "not"
It worked

que é imposible: uma entrada de diretório não pode ser tanto um arquivo ( -f ) quanto um diretório ( -d ).

Isso confirma a ideia de que o teste está realmente testando a string:

$ [[ \-fwd ]] && echo "It worked" || echo "not"
It worked

Testando com um arquivo

$ touch wds
$ [[ -fwd wds ]] && echo "It worked" || echo "not"
bash: conditional binary operator expected
bash: syntax error near 'wds'

Dá uma mensagem de falha em versões bash após 3.2.
Para outras versões, ele fornece uma resposta verdadeira (que é imposível para testes de arquivo, uma entrada de diretório não pode ser ao mesmo tempo um arquivo e um diretório).

Comparando esses dois testes, parece que apenas a primeira letra é usada:

$ b204sh -c '[[ -fd wds ]] && echo "It worked" || echo "not"'
It worked

$ b204sh -c '[[ -df wds ]] && echo "It worked" || echo "not"'
not

Provável erro corrigido na bash 4

Falha também em:

[[: No match.
[[: Command not found.
unknown condition: -fd # Versão 5.4.2
syntax error at line 3: wds 'inesperado' # Versão AJM 93u + 2012-08-01

    
por 27.12.2017 / 00:29