传递多个命令以聚集


12
flock -x -w 5 ~/counter.txt 'COUNTER=$(cat ~/counter.txt); echo $((COUNTER + 1)) > ~/counter.txt'

我如何将多个命令传递给flock上面的示例?

据我了解,flock采用不同的标志(-x表示排他,-w表示超时),然后是要锁定的文件,然后是要运行的命令。我不确定如何将两个命令传递给该函数(设置具有锁定文件内容的变量,然后递增该文件)。

我的目标是在每次脚本尝试访问文件时通过锁定文件来为文件创建某种程度的原子增量counter.txt

Answers:


8

显式调用Shell。

flock -x -w 5 ~/counter.txt sh -c 'COUNTER=$(cat counter.txt); echo $((COUNTER + 1)) > ~/counter.txt'

请注意,您更改的任何变量都是该Shell实例的本地变量。例如,该COUNTER变量将不会在调用脚本中更新:您必须从文件中读回它(但同时它可能已更改),或者作为命令的输出:

new_counter=$(flock -x -w 5 ~/counter.txt sh -c 'COUNTER=$(cat counter.txt); echo $((COUNTER + 1)) | tee ~/counter.txt')

太棒了,非常感谢!您提供的解释无疑使我摆脱了另一个小时的头痛
d -_- b 2013年

4

或者您可以聚集文件描述符

exec {counterfd}<~/counter.txt
flock -x -w 5 "$counterfd"
COUNTER=$(cat ~/counter.txt)
COUNTER=$(( COUNTER +1 ))
echo "$COUNTER" >~/counter.txt
exec {counterfd}<&-

与基于子外壳的方法不同,这还具有允许您直接使用计数器变量的好处。


请您解释一下exec {counterfd}吗?Debian本身会出错not found,但它的重定向返回0。很奇怪。
史蒂夫·阿蒙德

2

flock工具使用起来有些棘手,手册页也很短。手册页提供了三种使用该工具的方式:

  • flock [options] <file|directory> <command> [command args]
  • flock [options] <file|directory> -c <command>
  • flock [options] <file descriptor number>

这个问题的措辞方式我一定会使用的第三种形式flock。如果在手册页中进一步介绍了flock一些示例,这些示例显示了使用第三种形式的确切语法:

#!/bin/bash
(
 flock -n 9 || exit 1
 echo "commands executed under lock..."
 echo "go here..."
) 9>/tmp/mylockfile

我添加了#!/bin/bash

我已成功使用的这种形式flock

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.