8

In bash, a command link

echo test > actual.txt

will replace the contents of the file called actual.txt with "test", and create the file if it doesn't exist. However, if the file does exist, bash will just open it, truncate it, and write the new contents into the file.

Specifically, the redirect command fails in this scenario:

ln -s /some/illegal/path link.txt
echo test > link.txt

Bash 4.4.12 gives me the confusing error message link.txt: No such file or directory.

One way to avoid this is to make sure to delete the file before running the redirected command.

rm link.txt && echo test > link.txt

I was wondering, though, if there was some tweak of bash options or the redirect operator which will prevent this failure mode. Any ideas?

  • What if link.txt is a link to /dir/file where /dir is a file of type directory to which you have write and search permission, but /dir/file doesn't exist (and the redirection would create it without an error message)? What about if /dir/file exists but is not a regular file (device, fifo, directory...), or you don't have write permission to it or search permission to /dir? – Stéphane Chazelas Jan 31 '18 at 13:30
7

Trying to write to a dead symbolic link is equivalent to trying to write to a path that does not exist. There is no way to "tweak" the output redirection to create the path (including intermediate directories) in bash, and there are no shell options in bash that makes this automatic.

If the intermediate path exists, but the end point of the link does not, then it will be created by the redirection.

You may do something like

if [ -h file ] && [ ! -f file ]; then
    rm file
fi

to test whether "file" is a symbolic link (-h) and whether it refers to a regular file that exists (-f). If it is a symbolic link but does not refer to a file, then you delete it.

  • 1
    The point of my question was that I'm not trying to write to anything. I want to create a new file called link.txt, and there happens to be a symbolic link in the same location. To put this in the form of a question: why bother with the testing if I'm going to overwrite the file on the next line? I can just do rm -f and it will have the same effect. – itsadok Jan 31 '18 at 8:33
  • 3
    @itsadok Ah. Yes. Just doing rm -f filename before writing to it with the redirection would also solve your issue. But it also depends on whether you'd like to it to be in the current directory or in the directory where the end point of the symbolic link is located. – Kusalananda Jan 31 '18 at 8:35
  • You could still lack the permissions to rm the file or to write to it. As in many cases, you cannot prepare for everything. You need to assess which cases you really expect (if even as rare occasions) and therefore handle, which cases you consider so unlikely that you purposefully do not handle them, and accept that there will be a certain amount of cases you do not consider and thus cannot handle. – Alfe Jan 31 '18 at 13:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.