Я знаю, что некоторые оболочки хотя бы поддерживают операторы проверки файлов, которые обнаруживают, когда имя файла называет символическую ссылку.
Есть ли утилита POSIX 1, которая обеспечивает те же функциональные возможности?
1 Я не могу использовать правильную терминологию здесь. То, что я подразумеваю под «полезностью», – это автономный исполняемый файл, который находится где-то под /bin
, /usr/bin
и т. Д., В отличие от встроенной оболочки.
Вы ищете test
:
-h имя пути
True, если pathname разрешает файл, который существует и является символической ссылкой. False, если pathname не может быть разрешен или если pathname разрешает файл, который существует, но не является символической ссылкой. Если конечный компонент pathname является символической ссылкой, эта символьная ссылка не соблюдается.
Большинство оболочек имеют его как встроенный, но test
также существует как отдельная программа, которую можно вызывать из других программ без вызова промежуточной оболочки. Это касается большинства встроенных оболочек, которые могут иметь оболочки, за исключением тех, которые действуют на оболочку (специальные встроенные функции, такие как break
, export
, set
, …).
[ -h pathname ]
эквивалентно test -h pathname
; [
работает точно так же, как и test
, за исключением того, что в конце [
требуется дополнительный ]
аргумент. [
, как и test
, существует как отдельная программа.
Например:
$ ln -s foo bar $ /usr/bin/test -h bar && echo y y
Две утилиты могут сделать это для вас, file
и readlink
:
file some_symlink
отобразит some_symlink: symbolic link to 'some_target'
readlink some_symlink
выйдет с кодом 0, тогда как readlink some_file
выйдет с кодом 1 Обратите внимание, что код выхода хранится в переменной $?
, и может отображаться с помощью echo $?
,
Существует также stat
:
$ touch test $ ln -s test test_l $ stat test File: `test' Size: 0 Blocks: 0 IO Block: 4096 regular empty file Device: fc00h/64512d Inode: 4309 Links: 1 Access: (0664/-rw-rw-r--) Uid: ( 1000/ vagrant) Gid: ( 1000/ vagrant) Access: 2015-09-11 11:37:59.864165922 +0000 Modify: 2015-09-11 11:37:59.864165922 +0000 Change: 2015-09-11 11:37:59.864165922 +0000 Birth: - $ stat test_l File: `test_l' -> `test' Size: 4 Blocks: 0 IO Block: 4096 symbolic link Device: fc00h/64512d Inode: 7179 Links: 1 Access: (0777/lrwxrwxrwx) Uid: ( 1000/ vagrant) Gid: ( 1000/ vagrant) Access: 2015-09-11 11:38:07.220173955 +0000 Modify: 2015-09-11 11:38:07.220173955 +0000 Change: 2015-09-11 11:38:07.220173955 +0000 Birth: - $ stat -c "%F" test regular empty file $ stat -c "%F" test_l symbolic link
В качестве альтернативы вы можете использовать простой скрипт:
#!/bin/bash ls -alFQ | grep '^l'
Мантра Unix должна иметь небольшие простые утилиты, которые могут быть объединены вместе для достижения сложной задачи. Поэтому, хотя это технически не утилита POSIX, она очень близка к одной.
Если вы хотите получить фантазию, вы можете выбрать только часть возвращаемой строки:
#!/bin/bash ls -alFQ | grep '^l' | tr -s ' ' | cut -d ' ' -f 11
-f 11
возвращает файл, на который указывает ссылка, и -f 10
возвращает имя ссылки. Это работает только в том случае, если имена файлов не содержат пробелов, в противном случае это становится сложным – возможно, это возможно, но вам придется избегать пробелов или использовать шаблон, который больше, чем я хочу писать в данный момент ,
Если вы хотите что-то, возвращающее 0/1:
#!/bin/bash if [[ -n $(ls -alFQ | grep '^l') ]]; then exit else exit 1 fi