Esclarecimento sobre diferenças e uso do teste -f vs test -e em um shell script

4

Em uma revisão de código

Estou sendo destacado que devo alterar essa estrutura test :

[ ! -f "$1" ] &&
print_error_and_exit "The given argument is not an existing file."

para algo semelhante, especificamente:

[ ! -e "$1" ] ...

Mas não consigo encontrar nenhuma informação sobre esse test -e diferente do que está em info test ; citando capítulos relevantes:

16.3.3 File characteristic tests
--------------------------------

‘-e FILE’
     True if FILE exists.

16.3.1 File type tests
----------------------

‘-f FILE’
     True if FILE exists and is a regular file.

Pergunta

Como eu gostaria de entender 100% do que estou fazendo, posso pedir mais esclarecimentos sobre as diferenças e o uso desses dois tipos de comandos test ?

    
por Vlastimil 20.06.2018 / 06:34

3 respostas

4

Isso soa como meu comentário!

O teste com -e retornará true para arquivos não regulares: diretórios, pipes, soquetes, dispositivos etc.

Observe que os links simbólicos são um caso especial - test normalmente usa o tipo do arquivo apontado para , em vez do próprio link (exceto test -L , também conhecido como test -h ).

Na revisão referenciada, você pode querer ler de um FIFO. (Por outro lado, certamente não funcionará para ler em um diretório).

Mais adiante na revisão, você realmente não quer sobrescrever um dispositivo (embora você queira escrever no FIFO, ajuste-o de acordo com suas necessidades).

    
por 20.06.2018 / 11:49
9

Alguns "arquivos" são, na verdade, diretórios ( -d ), FIFOs ( -p ), nós de dispositivos ( -b e -c ), etc. Eles existem, mas não são arquivos regulares.

    
por 20.06.2018 / 06:37
3

Como você está usando o teste para evitar a criação de uma entrada de diretório com um nome que já exista, não importa qual seja a entrada (arquivo, diretório, fifo, nó de dispositivo ou outro) apenas que já existe e pode não ser criado (como o nome já está em uso).

O teste -f detecta apenas "arquivos regulares". O -e detecta alguns outros tipos.

Isto está mais próximo da sua intenção:

[ -e "$output_filename" ] && 
    print_error_and_exit 6 "Destination file name exists."

No entanto, o -e não detecta links. Você precisa usar essa construção:

[ -e "$output_filename" ] || [ -L "$output_filename" ] && 
    print_error_and_exit 6 "Destination file name exists."
    
por 20.06.2018 / 07:39