Search code examples
bashcplnrhel6

`ln -s` in a script acts as `cp`


Problem

I have this bash script:

ACTIVE_DB=$(grep -P "^[ \t]*db.active" config.properties | cut -d= -f2 | tr -s " ")
echo $ACTIVE_DB
if [ "$ACTIVE_DB" = "A" ]
then
    ln -sf config-b.properties config.properties
else
    ln -sf config-a.properties config.properties
fi

config-a.properties

db.active = A

config-b.properties

db.active = B

When I run the script, a hard copy (=cp) is performed and config.properties is often not a symbolic link (nor a physical link for that matter) but a whole new file with the same content as config-a.properties or config-b.properties.

$ ls -li
53 -rw-r--r-- 1 ogregoir ogregoir     582 Sep 30 15:41 config-a.properties
54 -rw-r--r-- 1 ogregoir ogregoir     582 Sep 30 15:41 config-b.properties
56 -rw-r--r-- 1 ogregoir ogregoir     582 Oct  2 11:28 config.properties

When I run this in the prompt manually line by line, I have no trouble and a symbolic link is indeed always created and config.properties points towards config-a.properties or config-b.properties.

$ ls -li
53 -rw-r--r-- 1 ogregoir ogregoir     582 Sep 30 15:41 config-a.properties
54 -rw-r--r-- 1 ogregoir ogregoir     582 Sep 30 15:41 config-b.properties
55 lrwxrwxrwx 1 ogregoir ogregoir      20 Oct  2 11:41 config.properties -> config-b.properties

Notes

  • No file is open anywhere else (I'm the only active user and the application using the configuration isn't running).
  • Sometimes ln -sf acts normally, but the usual rule is that it makes a hard copy.
  • The script is run from another directory, but cds to the directory where the config*.properties files are located before performing the actions here.
  • The script is way much longer, but this is the shortest example that reproduces the error.
  • bash version is 4.1.2 (it's local, so I don't care about shellshock).
  • ln version is 8.4.
  • Operating System: Red Hat Enterprise Linux Server release 6.5 (Santiago).
  • Filesystem used for that folder: ext4.

Question

  • Why doesn't my script consistently create a symbolic link but makes a hard copy?
  • How to force a symbolic link here?

Solution

  • I suspect you have some other script or code that is overwriting the symlinks. For example, sed -i will trash symlinks. There are a variety of commands and utilities that modify a file by creating a copy, modifying the copy, and then moving the copy over top of the original, which destroys the original symlink.