5

问题

我有这个 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

配置-a.properties

db.active = A

配置-b.properties

db.active = B

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

问题

  • 为什么我的脚本没有始终如一地创建符号链接,而是制作了硬拷贝?
  • 如何在此处强制使用符号链接?
4

2 回答 2

3

我怀疑您还有其他一些脚本或代码覆盖了符号链接。例如,sed -i将垃圾符号链接。有多种命令和实用程序可以通过创建副本、修改副本、然后将副本移动到原始文件之上来修改文件,这会破坏原始符号链接。

于 2014-10-14T22:24:04.563 回答
1

该问题的唯一可能答案(如所问):为什么ln按原样行事cp:它不能。

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

一些可能的替代方案:
1.- 该ln命令实际上是在进行硬链接。i-node 列表 ( ls -li) 确认 i-node 编号是不同的。所以,不,这不是原因。

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

3.-因为“脚本是从另一个目录运行的”。这里的要点是:文件系统中是否有其他文件具有相同的 i-node 编号(如果ln实际上是创建硬链接)。可以验证是否存在具有相同 i 节点的其他文件(使用列表中的 i 节点编号 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后面是问题的根源。

于 2014-10-12T10:32:04.720 回答