2015-11-18 30 views
0

我有一个bash脚本可以并行运行多次,我需要能够检查文件中的值并对其进行修改。理想情况下,我希望首先到达那里的任何脚本实例能够在不受其他实例干扰的情况下进行阅读和写作。我认为我可以用羊群做到这一点,但似乎有些命令会被忽略 - 我猜是因为它们无法锁定?使用flock在bash中读取和写入文件

这是我到目前为止有:

myfunc() { 
    { flock -x 3 ; count=$(cat <&3); } 3< countfile 
    { flock -x 3 ; echo $((count+1)) >&3; } 3> countfile 
} 

这是从一个子shell运行,所以我必须通过文件做计数。

因此,两件事情

  1. 这是没有使用相同的锁读写 - 像我倒是,但我不知道HOWTO做
  2. 为什么我有时读忽略?

谢谢!

+1

你可能可以用'flock'来做你想要的,假设所有进程都这样做(因为'flock'只提供*任意*锁定)。然而,目前还不清楚你的问题实际上是如何体现的。如果您提供一个可以重现您的问题的最小完整示例,您将获得更好的帮助。 –

+0

您现有的代码锁定文件,读取它,解锁它,再次锁定,写入并解锁它。这显然是不安全的,因为它意味着**第一个锁被释放和第二个锁发生**时,文件可能已被其他人改变。 –

回答

1

您不需要为读取和写入过程重复使用相同的描述符。在其他语言中,这将是一种代码异味,但bash没有本地支持在现有的FD中寻找,这是一个不幸的必要性。

myfunc() { 
    { 
    flock -x 3 || return 
    count=$(<countfile) 
    echo "$((count + 1))" >countfile 
    } 3<>countfile 
} 

这就是说 - 并非所有的解决方案都是原生的! @telotortium has written an excellent C helper可用于在预先打开的FD内查找;如果您要使用自己的代码来回溯到文件的开头(或者类似的将它截断为0并在那里移动FD),那么您可以重复使用单个文件描述符来进行读取和写入。

0

我跟着例子here。我不完全确定为什么切换到使用可变流描述符有帮助,但我完成了我所需要的。另一件不同的事情是,在这个例子中,他们使用了被锁定的子shell中的实际文件名,而不是实际引用流。

这是我的新东西,所以我欢迎评论。

+0

您能准确地显示**吗?**您是如何遵循该示例的?如何解决您的问题并不完全清楚,因此,新代码是否与问题中给出的问题相同(问题是:将锁分开而不是连续的互斥)。 –