使用 flock 和 lockfile 在 bash 中锁定文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28227739/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 12:17:37  来源:igfitidea点击:

Lock a file in bash using flock and lockfile

bash

提问by user3701179

i spent the better part of the day looking for a solution to this problem and i think i am nearing the brink ... What i need to do in bash is: write 1 script that will periodicly read your inputs and write them into a file and second script that will periodicly print out the complete file BUT only when something new gets written in, meaning it will never write 2 same outputs 1 after another. 2 scripts need to comunicate by the means of a lock, meaning script 1 will lock a file so that script 2 cant print anything out of it, then script 1 will write something new into that file and unlock it ( and then script 2 can print updated file ). The only hints we got was the usage of flock and lockfile - didnt get any hints on how to use them, exept that problem MUST be solved by flock or lockfile.

我花了一天的大部分时间寻找这个问题的解决方案,我想我已经接近边缘了......我需要在 bash 中做的是:编写 1 个脚本,它会定期读取您的输入并将它们写入一个文件和第二个脚本将定期打印出完整的文件,但只有在写入新内容时才会打印出来,这意味着它永远不会一个接一个地写入 2 个相同的输出。2 个脚本需要通过锁的方式进行通信,这意味着脚本 1 将锁定一个文件,以便脚本 2 无法从中打印任何内容,然后脚本 1 将向该文件中写入一些新内容并解锁它(然后脚本 2 可以打印更新后的文件 )。我们得到的唯一提示是 flock 和 lockfile 的使用——没有得到关于如何使用它们的任何提示,除了这个问题必须通过 flock 或 lockfile 解决。

edit: When i said i was looking for a solution i ment i tried every single combination of flock with those flags and i just couldnt get it to work.

编辑:当我说我正在寻找解决方案时,我尝试了所有带有这些标志的 flock 组合,但我无法让它发挥作用。

I will write pseudo code of what i want to do. A thing to note here is that this pseudocode is basicly the same as it is done in C .. its so simple, i dont know why everything has to be so complicated in bash.

我将编写我想做的伪代码。这里需要注意的一点是,这个伪代码与在 C 中完成的基本相同。

script 1:

脚本1:

place a lock on file text.txt ( no one else can read it or write to it) read input place that input into file ( not deleting previous text ) remove lock on file text.txt repeat

锁定文件 text.txt(其他人无法读取或写入文件)读取输入到文件中的输入位置(不删除之前的文本)取消锁定文件 text.txt 重复

script 2:

脚本2:

print out complete text.txt ( but only if it is not locked, if it is locked obviously you cant) repeat

打印出完整的 text.txt(但前提是它没有被锁定,如果它显然被锁定了你不能)重复

And since script 2 is repeating all the time, it should print the complete text.txt ONLY when something new was writen to it.

由于脚本 2 一直在重复,所以它应该只在写入新内容时才打印完整的 text.txt。

I have about 100 other commands like flock that i have to learn in a very short time and i spent 1 day only for 1 of those commands. It would be kind of you to at least give me a hint. As for man page ...

我有大约 100 个其他命令,例如 flock,我必须在很短的时间内学习这些命令,而我只花了 1 天时间来学习其中的 1 个命令。如果你至少给我一个提示,那就太好了。至于手册页...

I tried to do something like flock -x text.txt -c read > text.txt, tried every other combination also, but nothing works. It takes only 1 command, wont accept arguments. I dont even know why there is an option for command. I just want it to place a lock on file, write into it and then unlock it. In c it only takes flock("text.txt", ..).

我尝试做类似 flock -x text.txt -c read > text.txt 的事情,也尝试了所有其他组合,但没有任何效果。它只需要 1 个命令,不会接受参数。我什至不知道为什么有命令选项。我只是想让它锁定文件,写入文件然后解锁。在 c 中它只需要 flock("text.txt", ..)。

回答by Charles Duffy

Let's look at what this does:

让我们看看这是做什么的:

flock -x text.txt -c read > text.txt

First, it opens test.txtfor write (and truncates all contents) -- before doing anything else, including calling flock!

首先,它打开test.txt写入(并截断所有内容)——在做任何其他事情之前,包括调用flock!

Second, it tells flockto get an exclusive lock on the file and run the command read.

其次,它告诉flock获取文件的排他锁并运行命令read

However, readis a shell builtin, not an external command -- so it can't be called by a non-shell process at all, mooting any effect that it might otherwise have had.

然而,它read是一个内置的 shell,而不是一个外部命令——所以它根本不能被非 shell 进程调用,因此它可能会产生任何影响。



Now, let's try using flockthe way the man page suggests using it:

现在,让我们尝试使用flock手册页建议的使用方式:

{
  flock -x 3                       # grab a lock on file descriptor #3
  printf "Input to add to file: "  # Prompt user
  read -r new_input                # Read input from user
  printf '%s\n' "$new_input" >&3   # Write new content to the FD
} 3>>text.txt                      # do all this with FD 3 open to text.txt

...and, on the read end:

...而且,在阅读结束时:

{
  flock -s 3  # wait for a read lock
  cat <&3     # read contents of the file from FD 3
} 3<text.txt  # all of this with text.txt open to FD 3

You'll notice some differences from what you were trying before:

您会注意到与之前尝试的有些不同:

  • The file descriptor used to grab the lock is in append mode(when writing to the end), or in read mode (when reading), so you aren't overwriting the file before you even grab the lock.
  • We're running the readcommand (which, again, is a shell builtin, and so can onlybe run directly by the shell) by the shell directly, rather than telling the flockcommand to invoke it via the execvesyscall (which is, again, impossible).
  • 用于获取锁的文件描述符处于追加模式(写入末尾时)或读取模式(读取时),因此您在获取锁之前不会覆盖文件。
  • 我们正在直接由 shell运行read命令(这也是一个内置的 shell,因此只能由 shell 直接运行),而不是告诉flock命令通过execve系统调用来调用它(这又是不可能的) )。