3

Trying to make an if statement that checks if a file is a valid symlink (meaning it also exists).

I tried:

[ -h "$1" -a ! -e "$1" ]

... buut it doesn't work. I want to execute code if the file isn't a valid symlink, or doesn't exist at all.

Kusalananda
  • 320,670
  • 36
  • 633
  • 936
Freedo
  • 1,205
  • 6
  • 31
  • 57
  • You are using 6 arguments for test and more than 4 args are unspecified. Better divide it into more single purpose tests. – schily May 13 '20 at 10:44

1 Answers1

7

If the name in $1 is a valid symbolic link, then the -e test would be true. If it's a broken symbolic link, then the -e test would fail. The test would additionally fail if the name in $1 does not exist at all.

So, to test whether $1 is a broken symbolic link, or if it doesn't exist at all, it would be enough to use

if [ ! -e "$1" ]; then ...; fi

The test that you have is better written without the deprecated -a as

if [ ! -e "$1" ] && [ -h "$1" ]; then ...; fi

This tests whether $1 is an existing broken symbolic link.

Would you want to test for a valid symbolic link, use

if [ -e "$1" ] && [ -h "$1" ]; then ...; fi
Kusalananda
  • 320,670
  • 36
  • 633
  • 936
  • It might depend on the version, but on my machine (GNU core utils 8.32) `-e` does not check whether the link is broken. It returns true as long as the link file itself exists. – ThomasH Aug 15 '23 at 10:37
  • 1
    @ThomasH The `-e` test is handled by the shell, which is not part of coreutils (it would be `bash` or `dash` or `zsh` or some other shell). The shell would in turn implement the semantics imposed by the POSIX standard on the `-e` test, which requires the test to resolve any symbolic links and to fail if the given pathname can't be resolved. If your shell's `-e` test returns _true_ for a broken symbolic link, then this is a bug in that shell. – Kusalananda Aug 15 '23 at 11:32