脚本中的`ln -s`充当`cp`

时间:2014-10-02 09:59:09

标签: bash cp ln rhel6

问题

我有这个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通常不是符号链接(也不是物理链接),而是一个全新的文件与config-a.propertiesconfig-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.propertiesconfig-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行为正常,但通常的规则是它会制作硬拷贝。
  • 脚本从另一个目录运行,但cd运行到config*.properties文件所在的目录,然后再执行此操作。
  • 脚本更长,但这是重现错误的最短示例。
  • bash版本是4.1.2(它是本地的,所以我不关心shellshock)。
  • ln版本为8.4。
  • 操作系统:Red Hat Enterprise Linux Server 6.5版(圣地亚哥)。
  • 用于该文件夹的文件系统:ext4。

问题

  • 为什么我的脚本不能始终创建符号链接但是制作硬拷贝?
  • 如何在此强制使用符号链接?

2 个答案:

答案 0 :(得分:3)

我怀疑你有一些其他的脚本或代码覆盖了符号链接。例如,sed -i将废弃符号链接。有许多命令和实用程序可以通过创建副本,修改副本,然后将副本移动到原始文件顶部来修改文件,从而破坏原始符号链接。

答案 1 :(得分:1)

问题的唯一答案(如问题所示):为什么ln表现为cp:它不能。

唯一可能的答案是:您呈现给我们的不完全是正在执行的内容,或者还有其他运行的脚本会改变答案。

一些可能的选择:
1.- ln命令实际上正在进行硬链接。索引节点列表(ls -li)确认索引节点号是不同的。所以,不,这不是原因。

2.- ln是否有别名或功能?
这很容易检查。只需在Bash中发布type -a ln即可。结果将显示什么是bash解释ln。如果它只是文件/bin/ln,那么它是正确的 您确认没有涉及别名或功能。

3.- As"脚本从另一个目录运行"。 这里的要点是:文件系统中是否有其他文件具有相同的索引节点编号(如果ln实际上是在创建硬链接)。可以验证具有相同i节点的其他文件的存在(使用您的列表中的inode编号53,54,56):

find / -follow -inum <your inum>

4.-我希望您真正意识到config-b.properties实际上并不存在(作为文件)。编辑此类文件可能会删除该链接。

执行的实际脚本是否也在更改/更新文件内容?

Note01:请注意K技巧确实只解决了一次外部调用中的提取问题:     http://www.charlestonsw.com/perl-regular-expression-k-trick/

ACTIVE_DB=$(grep -Po "^[ \t]*db.active[ ]+=[ ]+\K." config.properties)

已经确认,实际执行的脚本中的sed -iconfig-b.properties后面是问题的根源。