Я пишу сценарий bash, который должен отличать обычный файл от символической ссылки. Я думал, что смогу сделать это с выражением if / test, но оно не работает так, как я ожидал:
$ 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
Почему это? И как я могу правильно сделать это?
-e
и-f
заключалась в том, что-e
она использовалась для того, чтобы узнать, существует ли файл (любого типа), и-f
была предназначена для проверки того, существует ли файл и является ли он обычным файлом. Кажется, я неправильно понял, что такое «обычный файл» ..-h
для типа файла, например, для символических ссылок,-p
для именованных каналов и т. Д.@Caleb правильно делает сценарий только для проверки символической ссылки. Однако часть о том, почему был исключен, и мне было любопытно. Если вы посмотрите на исходный код coreutils и ограничите вывод теста, вы увидите, что когда вы запускаете тест символьной ссылки, он использует lstat, а если вы используете тест -f, он на самом деле вызывает 'stat', следующий за символической ссылкой:
Из справочной страницы stat:
Это означает, что тест -f будет возвращать true, если указанное имя файла является символической ссылкой на обычный файл или сам обычный файл.
источник