如何检查符号链接是否存在


208

我正在尝试检查bash中是否存在符号链接。这是我尝试过的。

mda=/usr/mda
if [ ! -L $mda ]; then
  echo "=> File doesn't exist"
fi


mda='/usr/mda'
if [ ! -L $mda ]; then
  echo "=> File doesn't exist"
fi

但是,这不起作用。如果是“!” 被遗忘,它永远不会触发。而如果 '!' 在那里,它每次都会触发。


2
如果使用[[!-D $ mda]]正常工作..
DMin

Answers:


327

-L如果“文件”存在并且是符号链接(链接的文件可能存在或不存在),则返回true。您想要-f(如果文件存在并且是常规文件,则返回true),或者只是-e(如果文件存在而与类型无关,则返回true)。

根据GNU手册页-h与相同-L,但根据BSD手册页,不应使用:

-h file 如果文件存在且为符号链接,则为True。保留该运算符是为了与该程序的早期版本兼容。不要依靠它的存在;使用-L代替。


2
我正在寻找符号链接是否不存在。!-h或!-L应该用于符号链接,否则!-e应该起作用。

48
为了像我一样通过Google帮助任何人,使用的完整语法!if ! [ -L $mda ]; then .... fi 将感叹号放在方括号之外
山姆

19
只是想在@Sam给出的提示中添加一些内容;在进行此类操作时,请确保将文件名放在引号中,以防止出现空格问题。例如if [ ! -L "$mda" ]; then ... fi(注:if [ ! ... ]if ! [ ... ]相同:)
Thomas Vervest 2013年

2
您真的看到-L和-h之间的区别吗?在我的bash(版本4.2.53(1)-发行版(x86_64-redhat-linux-gnu)中,man bash对于-L和-h都是相同的,并且它们的行为相同,即,他们检查文件实际上是否是链接,并且不要“不在乎是否链接到文件存在与否。
菲利普lhardy

3
是的,-L而且-h都是相同的man test也证实了这一点。
Sparhawk

39

-L是文件是否存在的测试,也是符号链接

如果您不想测试文件是否为符号链接,而只是测试它是否存在而不论类型(文件,目录,套接字等),则可以使用-e

因此,如果file是真正的文件,而不仅仅是符号链接,则可以执行所有这些测试并获得退出状态,该退出状态的值表示错误情况。

if [ ! \( -e "${file}" \) ]
then
     echo "%ERROR: file ${file} does not exist!" >&2
     exit 1
elif [ ! \( -f "${file}" \) ]
then
     echo "%ERROR: ${file} is not a file!" >&2
     exit 2
elif [ ! \( -r "${file}" \) ]
then
     echo "%ERROR: file ${file} is not readable!" >&2
     exit 3
elif [ ! \( -s "${file}" \) ]
then
     echo "%ERROR: file ${file} is empty!" >&2
     exit 4
fi

16
-e "${file}"如果符号链接存在但其目标不存在,则失败。
Flimm

1
与Flimm相同的结果。我在OS X上。对我而言,-L和-h用于符号链接,但不适用于-e或-f。
pauljm 2014年

2
@Flimm,所以,如果我只想测试文件名是否已被使用(是没有目标的文件还是符号链接),最好的方法是什么?显然-e不起作用
dragonxlwang

38

您可以检查符号链接是否存在,并且没有被破坏:

[ -L ${my_link} ] && [ -e ${my_link} ]

因此,完整的解决方案是:

if [ -L ${my_link} ] ; then
   if [ -e ${my_link} ] ; then
      echo "Good link"
   else
      echo "Broken link"
   fi
elif [ -e ${my_link} ] ; then
   echo "Not a link"
else
   echo "Missing"
fi

2
-L测试是否存在符号链接,是否断开。通过与-e组合,可以测试链接是否也有效(链接到目录或文件)。投票给这个解决方案,因为我发现捕获这一方面很重要。
TorbjörnÖsterdahl

14

也许这就是您想要的。检查文件是否存在并且不是链接。

试试这个命令:

file="/usr/mda" 
[ -f $file ] && [ ! -L $file ] && echo "$file exists and is not a symlink"

8

使用readlink怎么样?

# if symlink, readlink returns not empty string (the symlink target)
# if string is not empty, test exits w/ 0 (normal)
#
# if non symlink, readlink returns empty string
# if string is empty, test exits w/ 1 (error)
simlink? () {
  test "$(readlink "${1}")";
}

FILE=/usr/mda

if simlink? "${FILE}"; then
  echo $FILE is a symlink
else
  echo $FILE is not a symlink
fi

4

该文件真的是符号链接吗?如果不是,则通常的存在检验为-r-e

请参阅man test


3

如果要测试文件是否存在,则需要-e而不是-L。-L测试符号链接。


我正在寻找符号链接是否不存在。!-h或!-L应该用于符号链接,否则!-e应该起作用。

3
您想要的不清楚。该文件存在并且不是符号链接?然后测试两个 -e和!-h。
Andrew Lazarus

3
  1. 首先,您可以使用以下样式:

    mda="/usr/mda"
    if [ ! -L "${mda}" ]; then
      echo "=> File doesn't exist"
    fi
  2. 如果您想以更高级的风格进行操作,可以如下所示:

    #!/bin/bash
    mda="$1"
    if [ -e "$1" ]; then
        if [ ! -L "$1" ]
        then
            echo "you entry is not symlink"
        else
            echo "your entry is symlink"
        fi
    else
      echo "=> File doesn't exist"
    fi

上面的结果是这样的:

root@linux:~# ./sym.sh /etc/passwd
you entry is not symlink
root@linux:~# ./sym.sh /usr/mda 
your entry is symlink
root@linux:~# ./sym.sh 
=> File doesn't exist

如果文件存在但不是链接或悬空链接,则第一次调用是错误的。如果路径是悬挂的符号链接,则第二个错误。
乔纳森·托默
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.