Estou escrevendo um script bash que precisa distinguir um arquivo regular de um link simbólico. Eu pensei que poderia fazer isso com a expressão if / test, mas não funciona como eu esperava:
$ touch regular_file
$ test -f regular_file; echo $?
0
$ test -h regular_file; echo $?
1
$ ln -s regular_file symlink
$ test -h symlink; echo $?
0
$ test -f symlink; echo $?
0
Por que é que? E como posso fazer isso corretamente?
-e
e-f
foi-e
usada para saber se existia um arquivo (de qualquer tipo) e-f
era especificamente para testar se o arquivo existia e era um arquivo normal. Parece que eu mal o que um "arquivo regular" era ..-h
para links simbólicos,-p
para pipes nomeados, etc.O @Caleb está correto ao fazer o script apenas testar o link simbólico. No entanto, a parte sobre o porquê foi deixada de fora e eu fiquei curioso. Se você olhar o código fonte do coreutils e rastrear a saída do teste, poderá ver que, quando executa o teste do link simbólico, ele usa lstat e, se você usa o teste -f, na verdade, chama 'stat', que segue o link simbólico:
Na página do manual stat:
Isso significa que o teste -f retornará verdadeiro, desde que o nome do arquivo especificado seja um link simbólico para um arquivo comum ou para um arquivo comum.
fonte