linux bash 防止后台进程聚集

linux bash 防止后台进程聚集

我的脚本创建了 flock。这可以防止我运行两次。脚本可以执行另一个脚本,这样就出现了问题。有时另一个脚本会在后台留下进程。不幸的是,它们继承了 flock,我不需要这个。是否有任何包装器在执行指定的可执行文件之前关闭一些文件句柄?

我使用 linux debian,但它不是重要的 linux 发行版或版本。

详细场景:

  1. 我的脚本A已运行
  2. 我的脚本 A 让人蜂拥而至
  3. 我的脚本 A 运行外部可执行文件 B
  4. 外部B作为后台运行可执行文件C(继承flock)
  5. 外部 B 完成并将 C 留在后台(继承羊群)
  6. 我的脚本 A 完成,因为 B 完成
  7. 另一个循环,我的脚本 A 已运行(如第 1 点)
  8. 我的脚本 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仅存在于主脚本中,而包装器会破坏被调用脚本及其子脚本中的继承。

相关内容