如何在 OSX 上使用 test -h 或 test -L?

如何在 OSX 上使用 test -h 或 test -L?

我正在尝试在 shell 脚本中检测文件是否是指向目录的符号链接。我正在这样做:

if [[ -L "$out_dir" && -d "$out_dir" ]]
then
    echo "Dir is a symlink"
else
    echo "Dir is not a symlink"
fi

但是,这个方法失败了。下面是一些实验:

bash-3.2$ ls -ail ..
共 16
8004466 drwxr-xr-x 10 用户名 1177235957 340 7月 18日 15:41 ./
1020189 drwxr-xr-x 10 用户名 1177235957 340 7月 18日 15:16 ../
8004467 drwxr-xr-x 12 用户名 1177235957 408 7月 18日 15:16 .git/
8004528 -rw-r--r-- 1 用户名 1177235957 501 7月 18日 15:16 .gitignore
8004919 lrwxr-xr-x 1 用户名 1177235957 22 Jul 18 15:41 依赖项 -> ../../lmi/Dependencies

因此../Dependencies,根据 ls,是一个符号链接,但是:

bash-3.2$ 测试 -L ../Dependencies
bash-3.2$ 回显 $?
0
bash-3.2$ 测试 -h ../Dependencies
bash-3.2$ 回显 $?
0

这两个不应该都返回 1 吗?我是否误解了它的工作原理?如何实现我的目标,即检测文件是否是指向目录的符号链接?

答案1

您的实验的退出值是正确的。当test实用程序评估表达式时,如果表达式评估结果为真,test则返回零(真)退出状态;否则返回1(假)

因此,在您的示例中,test -L ../Dependencies返回 0(真),因为../Dependencies是符号链接。如果../Dependencies 不是符号链接test将返回 1(false)。

shell 脚本if语句是正确的,但您可以添加echo命令来查看 shell 脚本运行时是否存在其他问题。例如,您可以在语句echo前添加两个命令if

echo "path is '$PWD'"
echo "out_dir is '$out_dir'"

答案2

我会选择一个更复杂的解决方案(因为这适合我的个性,但现在这并不重要......)

for x in $(ls -lp|egrep ^[dl].*\/$); do 
   case $(echo $x|cut -c 1) in 
      "d") echo "This is a dir";; 
      "l") echo "This is a link";;
   esac
done

简而言之,ls -lp打印所有目录的长格式,末尾带有斜杠。长格式的第一个字符告诉我们模式(d用于目录、l用于链接、-用于常规文件等)。有了这些信息,我们可以使用egrep来过滤以ls结尾的目录和链接列表/,并使用来进一步过滤我们的列表。注意:由于 中的选项,case此循环还将过滤掉链接文件-pls

答案3

我最终得到了以下解决方案:

function is_sym_link()
{
    readlink $1 > /dev/null
    return $?
}

它可能无法覆盖所有情况,但对于我的环境来说已经足够了。不幸的是,我不知道为什么原来的版本不起作用。

相关内容