Различение регулярного файла от символьной ссылки

Стандартный путь с wc, который берет аргументы для определения то, что это должно считать (байты, символы, слова, и т.д.); -l для строк:

$ wc -l file.txt
1020 file.txt
22
04.10.2011, 15:16
2 ответа

Похоже, что Вы просто скремблируете свои тесты немного. Вы не должны запускать оба теста, единственный, в котором Вы нуждаетесь для этого случая, -h один, чтобы сказать Вам, если файл является символьной ссылкой.

test -h file && echo "is symlink" || echo "is regular file"

-f тест только говорит Вам, если объект является файлом. Это возвратилось бы 0 если это было каталогом или узлом устройства или символьной ссылкой на каталог, но возвратится 1 на символьной ссылке на файл.

Если бы также необходимо было знать, была ли это символьная ссылка на файл, а не каталог, необходимо было бы объединить результаты обоих тестов с определенной логикой.

20
27.01.2020, 19:43
  • 1
    раздела, Поскольку я понял из документов, различия между -e и -f было это -e использовался, чтобы знать, существовал ли файл (какого-либо типа), и -f должен был конкретно протестировать, если бы файл существовал и был регулярным файлом. Кажется, что я неправильно понял, каков "регулярный файл" был.. –  Nupraptor 04.10.2011, 15:24
  • 2
    @Nupraptor: Да, Вы неправильно поняли документы. Символьную ссылку считают регулярным файлом в противоположность некоторым из других типов узлов, которыми файл мог быть (узел блочного устройства, узел устройства посимвольного ввода-вывода, каталог, и т.д.). Если Вы хотите знать, какой файл это - Вы, должны выполнить тип файла определенный тест как -h для символьных ссылок, -p для именованных каналов, и т.д. –  Caleb 04.10.2011, 15:35
  • 3
    Затем как я тестирую, если файл является регулярным файлом в том смысле, что не канал, ни символьная ссылка и т.д.? Я должен открыть другой вопрос для этого? –  Nupraptor 04.10.2011, 17:04
  • 4
    @Nupraptor: единственный странный случай является символьной ссылкой, которая связывается с регулярным файлом. Иначе, если это тестирует как регулярный файл, это - регулярный файл. –  David Schwartz 05.10.2011, 15:06
  • 5
    Никакая удача. Вот моя строка. Это все еще работает как корень. Я проверил страницы справочника, и я все еще не знаю, что сделать об этом. start-stop-daemon --start --quiet --background -u www-data -g www-data --exec ${MONOSERVER} --pidfile /path/monoserve.pid --make-pidfile -- /applications=${WEBAPPS} /socket=unix:/path/monoserve.pid ---------121 тест--------66117----f каталог возвратит 1 не 0: тест-f.; $ эха? (выводы 1) –  polynomial 06.10.2011, 06:51

@Caleb корректен о создании сценария просто протестировать на символьную ссылку. Однако часть о том, почему был не учтен и мне было любопытно. При рассмотрении coreutils исходного кода и strace вывод теста, Вы видите, что, когда Вы запускаете тест символьной ссылки, он использует lstat и если Вы использующий-f тестируете его, на самом деле называет 'статистику', которая следует за символьной ссылкой:

$ 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() 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, пока указанное имя файла является символьной ссылкой на регулярный файл или сам регулярный файл.

7
27.01.2020, 19:43

Теги

Похожие вопросы