【发布时间】:2014-11-27 07:17:51
【问题描述】:
问题
我有这个 bash 脚本:
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
当我运行脚本时,会执行硬拷贝 (=cp),config.properties 通常不是符号链接(也不是物理链接),而是与 @ 内容相同的全新文件987654326@或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
当我在提示符中逐行手动运行时,我没有遇到任何问题,并且确实总是会创建一个符号链接,并且config.properties 指向config-a.properties 或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
注意事项
- 在其他任何地方都没有打开任何文件(我是唯一的活动用户,并且使用该配置的应用程序没有运行)。
- 有时
ln -sf行为正常,但通常的规则是制作硬拷贝。 - 脚本从另一个目录运行,但在执行此处操作之前,
cds 到config*.properties文件所在的目录。 - 脚本要长得多,但这是重现错误的最短示例。
-
bash版本是 4.1.2(它是本地的,所以我不关心 shellshock)。 -
ln版本为 8.4。 - 操作系统:Red Hat Enterprise Linux Server 6.5 版(圣地亚哥)。
- 用于该文件夹的文件系统:ext4。
问题
- 为什么我的脚本没有始终如一地创建符号链接,而是制作了硬拷贝?
- 如何在此处强制使用符号链接?
【问题讨论】:
-
ln命令将不会创建副本。从不 -
是的,我可以阅读
man ln,但它确实...随机! -
抱歉,我无法通过 RHEL6.0 和 100.000 更改链接重现此问题:
cp /etc/passwd /tmp/config-a.properties; cp /etc/passwd /tmp/config-b.properties; cd /tmp; c=0; while true; do ln -sf config-a.properties config.properties; [ ! -h config.properties ] && exit; ln -sf config-b.properties config.properties; [ ! -h config.properties ] && exit; echo $c; c=$((c+1)); done -
在每次调用之前添加
command -v ln以显示ln实际调用的内容(以排除shell 函数或像/this/is/wrong/ln这样的意外二进制文件)。由于符号链接的目标甚至不需要存在,因此前面的命令不太可能对您正在观察的内容产生任何影响。 -
我怀疑您有一些其他脚本或代码正在覆盖符号链接。例如,
sed -i将删除符号链接。有多种命令和实用程序可以通过创建副本、修改副本、然后将副本移动到原始文件之上来修改文件,这会破坏原始符号链接。或者另一种解释:您没有运行您认为的脚本,或者没有修改您认为的文件。