寻找 POSIX 实用程序来测试文件名是否是符号链接

寻找 POSIX 实用程序来测试文件名是否是符号链接

我知道某些 shell 至少支持文件测试运算符来检测文件名何时命名符号链接。

有 POSIX 吗公用事业1提供相同的功能?


1我在这里可能没有使用正确的术语。我所说的“实用程序”是指位于/bin、等下的独立可执行文件/usr/bin,而不是内置的 shell。

答案1

您正在寻找test:

-h 路径名

如果路径名解析为存在且是符号链接的文件,则为 True。如果无法解析路径名,或者路径名解析为存在但不是符号链接的文件,则返回 False。如果路径名的最后一个组成部分是符号链接,则不遵循该符号链接。

大多数 shell 将其作为内置程序,但test也作为独立程序存在,可以从其他程序调用它,而无需调用中间 shell。对于 shell 可能具有的大多数内置函数来说,情况都是如此,除了那些作用于 shell 本身的内置函数(特殊的内置函数,如breakexportset、 ...)。

[ -h pathname ]相当于test -h pathname[工作方式与 完全相同test,只是最后[需要一个额外的参数。 ,就像 一样,作为独立程序存在。][test

例如:

$ ln -s foo bar
$ /usr/bin/test -h bar && echo y
y

答案2

两个实用程序可以为您做到这一点,file并且readlink

  1. file some_symlink将显示some_symlink: symbolic link to 'some_target'
  2. readlink some_symlink将以代码 0 退出,而readlink some_file以代码 1 退出

注意退出代码存储在变量中$?,并且可以用 来显示echo $?

答案3

还有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

答案4

或者,您可以使用一个简单的脚本:

#!/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

相关内容