@Caleb правильно делает сценарий только для проверки символической ссылки. Однако часть о том, почему был исключен, и мне было любопытно. Если вы посмотрите на исходный код coreutils и ограничите вывод теста, вы увидите, что когда вы запускаете тест символьной ссылки, он использует lstat, а если вы используете тест -f, он на самом деле вызывает 'stat', следующий за символической ссылкой:
$ ln -s varnish_config XXX
$ strace -s 2000 test -L XXX 2>&1 | grep XXX
execve("/usr/bin/test", ["test", "-L", "XXX"], [/* 47 vars */]) = 0
lstat("XXX", {st_mode=S_IFLNK|0777, st_size=14, ...}) = 0
$ strace -s 2000 test -L varnish_config 2>&1 | grep varnish
execve("/usr/bin/test", ["test", "-L", "varnish_config"], [/* 47 vars */]) = 0
lstat("varnish_config", {st_mode=S_IFREG|0664, st_size=1046, ...}) = 0
$ strace -s 2000 test -f XXX 2>&1 | grep XXX
execve("/usr/bin/test", ["test", "-f", "XXX"], [/* 47 vars */]) = 0
stat("XXX", {st_mode=S_IFREG|0664, st_size=1046, ...}) = 0
Из справочной страницы stat:
stat() stats the file pointed to by path and fills in buf.
lstat() is identical to stat(), except that if path is a symbolic link,
then the link itself is stat-ed, not the file that it refers to.
Это означает, что тест -f будет возвращать true, если указанное имя файла является символической ссылкой на обычный файл или сам обычный файл.
-e
и-f
заключалась в том, что-e
она использовалась для того, чтобы узнать, существует ли файл (любого типа), и-f
была предназначена для проверки того, существует ли файл и является ли он обычным файлом. Кажется, я неправильно понял, что такое «обычный файл» ..