如何从多个脚本同步(锁定/解锁)对 bash 中文件的访问?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2319091/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I synchronize (lock/unlock) access to a file in bash from multiple scripts?
提问by Debugger
I'm writing scripts that will run in parallel and will get their input data from the same file. These scripts will open the input file, read the first line, store it for further treatment and finally erase this read line from the input file.
我正在编写并行运行的脚本,并从同一个文件中获取输入数据。这些脚本将打开输入文件,读取第一行,将其存储以供进一步处理,最后从输入文件中删除该读取行。
Now the problem is that multiple scripts accessing the file can lead to the situation where two scripts access the input file simultaneously and read the same line, which produces the unacceptable result of the line being processed twice.
现在的问题是,多个脚本访问文件会导致两个脚本同时访问输入文件并读取同一行的情况,从而产生该行被处理两次的不可接受的结果。
Now one solution is to write a lock file (.lock_input
) before accessing the input file, and then erase it when releasing the input file, but this solution is not appealing in my case because sometimes NFS slows down network communication randomly and may not have reliable locking.
现在一种解决方案是.lock_input
在访问输入文件之前写一个锁定文件 ( ),然后在释放输入文件时将其擦除,但这种解决方案在我的情况下没有吸引力,因为有时 NFS 会随机减慢网络通信并且可能没有可靠的锁定.
Another solution is to put a process lock instead of writing a file, which means the first script to access the input file will launch a process called lock_input, and the other scripts will ps -elf | grep lock_input
. If it is present on the process list they will wait. This may be faster than writing to the NFS but still not perfect solution ...
另一种解决方案是放置进程锁而不是写入文件,这意味着访问输入文件的第一个脚本将启动一个名为 lock_input 的进程,其他脚本将ps -elf | grep lock_input
. 如果它出现在进程列表中,他们将等待。这可能比写入 NFS 更快,但仍然不是完美的解决方案......
So my question is: Is there any bash command (or other script interpreter) or a service I can use that will behave like semaphore or mutex locks used for synchronization in thread programming?
所以我的问题是:是否有任何 bash 命令(或其他脚本解释器)或我可以使用的服务,其行为类似于线程编程中用于同步的信号量或互斥锁?
Thank you.
谢谢你。
Small rough example:
粗略的小例子:
Let's say we have input_file as following:
假设我们有 input_file 如下:
Monday Tuesday Wednesday Thursday Friday Saturday Sunday
Treatment script : TrScript.sh
处理脚本:TrScript.sh
#!/bin/bash
NbLines=$(cat input_file | wc -l)
while [ ! $NbLines = 0 ]
do
FirstLine=$(head -1 input_file)
echo "Hello World today is $FirstLine"
RemainingLines=$(expr $NbLines - 1 )
tail -n $RemainingLines input_file > tmp
mv tmp input_file
NbLines=$(cat input_file | wc -l)
done
Main script:
主要脚本:
#! /bin/bash
./TrScript.sh &
./TrScript.sh &
./TrScript.sh &
wait
The result should be:
结果应该是:
Hello World today is Monday Hello World today is Tuesday Hello World today is Wednesday Hello World today is Thursday Hello World today is Friday Hello World today is Saturday Hello World today is Sunday
采纳答案by Chris Johnsen
I have always liked the lockfileprogram (sample search result for lockfilemanpage) from the procmailset of tools (should be available on most systems, though it might not be installed by default).
我一直很喜欢procmail工具集中的lockfile程序(lockfilemanpage 的示例搜索结果)(应该在大多数系统上可用,但默认情况下可能没有安装)。
It was designed to lock mail spool files, which are (were?) commonly mounted via NFS, so it does work properly over NFS (as much as anything can).
它旨在锁定邮件假脱机文件,这些文件(是?)通常通过 NFS 挂载,因此它确实可以通过 NFS 正常工作(尽可能多)。
Also, as long as you you are making the assumption that all your ‘workers' are on the same machine (by assuming you can check for PIDs, which may not work properly when PIDs eventually wrap), you could put your lock file in some other, local, directory (e.g. /tmp) while processing files hosted on an NFS server. As long as all the workers use the same lock file location (and a one-to-one mapping of lockfile filenames to locked pathnames), it will work fine.
此外,只要您假设所有“工人”都在同一台机器上(假设您可以检查 PID,当 PID 最终包装时可能无法正常工作),您可以将您的锁定文件放在一些处理托管在 NFS 服务器上的文件时的其他本地目录(例如 /tmp)。只要所有工作人员都使用相同的锁定文件位置(以及锁定文件文件名到锁定路径名的一对一映射),它就可以正常工作。
回答by me.
use
用
line=`flock $lockfile -c "(gawk 'NR==1' < $infile ; gawk 'NR>1' < $infile > $infile.tmp ; mv $infile.tmp $infile)"`
for accessing the file you want to read from. This uses file locks, though.
用于访问您要读取的文件。不过,这使用文件锁。
gawk NR==1 < ...
prints the first line of the input
打印输入的第一行
回答by tiian
Using FLOM (Free LOck Manager)tool your main script can become as easy as:
使用FLOM(自由锁管理器)工具,您的主脚本可以变得如此简单:
#!/bin/bash
flom -- ./TrScript.sh &
flom -- ./TrScript.sh &
flom -- ./TrScript.sh &
wait
if you are running the script inside a single host and something like:
如果您在单个主机内运行脚本,例如:
flom -A 224.0.0.1 -- ./TrScript.sh &
if you want to distribute your script on many hosts. Some usage examples are available at this URL: http://sourceforge.net/p/flom/wiki/FLOM%20by%20examples/
如果您想在许多主机上分发您的脚本。此 URL 提供了一些使用示例:http: //sourceforge.net/p/flom/wiki/FLOM%20by%20examples/