我的脚本创建了 flock。这可以防止我运行两次。脚本可以执行另一个脚本,这样就出现了问题。有时另一个脚本会在后台留下进程。不幸的是,它们继承了 flock,我不需要这个。是否有任何包装器在执行指定的可执行文件之前关闭一些文件句柄?
我使用 linux debian,但它不是重要的 linux 发行版或版本。
详细场景:
- 我的脚本A已运行
- 我的脚本 A 让人蜂拥而至
- 我的脚本 A 运行外部可执行文件 B
- 外部B作为后台运行可执行文件C(继承flock)
- 外部 B 完成并将 C 留在后台(继承羊群)
- 我的脚本 A 完成,因为 B 完成
- 另一个循环,我的脚本 A 已运行(如第 1 点)
- 我的脚本 A 导致集群失败,因为 C 仍在运行
我想要使用封闭的聚集文件句柄准确运行外部可执行文件 B。应保留 Flock,直到只有我的脚本 A 正在运行。我不希望在 2 到 3 点之间出现紧密的羊群,因为会有“羊群洞”。有没有类似这样的包装操作系统?
答案1
根据羊群的手册页,这是 -u 或 --unlock 选项的一种用法:
-u,--解锁
放下一把锁。这通常不是必需的,因为关闭文件时会自动删除锁。但是,在特殊情况下可能需要它,例如,如果封闭的命令组可能分叉了不应持有锁的后台进程。
因此规定的技术是这样的:
(
flock 200 | exit 99
# some commands that should be guarded by the lock
# some of them fork daemons that keep our lock file open
flock --unlock 200 # we're done with the lock, we can release it
) 200>/path/to/lock-file
答案2
以下代码获取锁并trap
确保在脚本退出时释放锁。子进程继承该锁,但在flock --unlock 200
执行后不保留该锁。
flock 200 | exit 1
trap "flock --unlock 200" EXIT
# The rest of the script...
注意:trap
一次只能有 1 个有效。如果您需要在退出陷阱中执行多个命令,那么您需要将它们放入一个方法中或将它们组合起来trap "flock --unlock 200; echo Bye" EXIT
。
答案3
我昨天写了一些包装。它关闭所有不需要的句柄,然后调用指定的命令。不幸的是,它不检查句柄类型,关闭除某些已知句柄之外的所有句柄。
<==== file: wrapper.sh ====>
#!/bin/bash
for fd in $(ls /proc/$$/fd); do
case "$fd" in
0|1|2|255)
;;
*)
eval "exec $fd>&-"
;;
esac
done
exec $1 $2 $3 $4 $5 $6 $7 $8 $9
你通过以下方式计算:
wrapper.sh some_command command parameters
我可以使用这个变形器步骤3在我的通话场景中。然后,flock仅存在于主脚本中,而包装器会破坏被调用脚本及其子脚本中的继承。