我有一个shell脚本,大致如下所示:
#!/bin/bash
# Script variables
NPM="/usr/bin/npm"
# Start several sub-processes in a loop in parallel
for i in {1..4}; do
$NPM run -s long_running_script >> /path/to/script/output/stream.tsv &
done
wait
为确保长时间运行的脚本持续运行,但为了防止多个并行实例,我使用cron通过cron调用它:
0 * * * * /usr/bin/flock -n /var/lock/my_lock_file /path/to/script/hourly.sh
我尝试过使用trap并将其添加到脚本的开头,但没有运气:
trap "kill $(jobs -p)" EXIT
上述不同的变化也没有,例如trap "kill -HUP -$$"
。似乎陷阱甚至没有被执行(大概是因为它等待$NPM run -s long_running_script
的所有实例完成?)。
我能够从不同的脚本中杀死进程,知道子孙的名字,然后执行pkill
,但我更喜欢更通用的解决方案。有没有办法杀死从shell脚本生成的所有进程,而无需手动跟踪所有生成的进程及其后续子进程?
在脚本代码段中添加了更多详细信息,以显示我管道输出。以下是NPM生成的进程的快照(在每个循环的迭代中):
UID PID PPID C STIME TTY TIME CMD
root 4124 4122 10 14:51 ? 00:00:01 npm
root 4134 4124 0 14:51 ? 00:00:00 sh -c node long_running_script.js
root 4135 4134 42 14:51 ? 00:00:03 node long_running_script.js
来自lsof的相应输出:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
npm 4124 root cwd DIR 43,0 4096 2753156 /path/to/working/directory
npm 4124 root rtd DIR 43,0 4096 2 /
npm 4124 root txt REG 43,0 11187096 1971997 /usr/bin/nodejs
npm 4124 root mem REG 43,0 25913104 2238299 /usr/lib/x86_64-linux-gnu/libicudata.so.55.1
npm 4124 root mem REG 43,0 1864888 2757931 /lib/x86_64-linux-gnu/libc-2.23.so
npm 4124 root mem REG 43,0 89696 2752592 /lib/x86_64-linux-gnu/libgcc_s.so.1
npm 4124 root mem REG 43,0 1088952 2757928 /lib/x86_64-linux-gnu/libm-2.23.so
npm 4124 root mem REG 43,0 1566440 2234802 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
npm 4124 root mem REG 43,0 1636360 2238295 /usr/lib/x86_64-linux-gnu/libicuuc.so.55.1
npm 4124 root mem REG 43,0 2496856 2238296 /usr/lib/x86_64-linux-gnu/libicui18n.so.55.1
npm 4124 root mem REG 43,0 2361856 2752549 /lib/x86_64-linux-gnu/libcrypto.so.1.0.0
npm 4124 root mem REG 43,0 428384 2752550 /lib/x86_64-linux-gnu/libssl.so.1.0.0
npm 4124 root mem REG 43,0 14608 2757925 /lib/x86_64-linux-gnu/libdl-2.23.so
npm 4124 root mem REG 43,0 138696 2757942 /lib/x86_64-linux-gnu/libpthread-2.23.so
npm 4124 root mem REG 43,0 31712 2757938 /lib/x86_64-linux-gnu/librt-2.23.so
npm 4124 root mem REG 43,0 142640 2238078 /usr/lib/x86_64-linux-gnu/libuv.so.1.0.0
npm 4124 root mem REG 43,0 104824 2752763 /lib/x86_64-linux-gnu/libz.so.1.2.8
npm 4124 root mem REG 43,0 162632 2757932 /lib/x86_64-linux-gnu/ld-2.23.so
npm 4124 root 0r CHR 1,3 0t0 1031 /dev/null
npm 4124 root 1w REG 43,0 2488489 2752561 /path/to/script/output/stream.tsv
npm 4124 root 2w REG 43,0 4669 1837068 /var/log/my_log_file
npm 4124 root 3r REG 0,17 0 8980 /run/lock/my_lock_file
npm 4124 root 4r FIFO 0,9 0t0 8092 pipe
npm 4124 root 5w FIFO 0,9 0t0 8092 pipe
npm 4124 root 6u a_inode 0,10 0 2049 [eventpoll]
npm 4124 root 7r FIFO 0,9 0t0 8093 pipe
npm 4124 root 8w FIFO 0,9 0t0 8093 pipe
npm 4124 root 9u a_inode 0,10 0 2049 [eventfd]
这就是当我打电话给fuser -k
时会发生什么,root@host:/ fuser -v /var/lock/my_file_lock
/run/lock/my_file_lock: root 26156 f.... flock
root 26157 f.... hourly.sh
root 26159 f.... npm
root 26225 f.... npm
root 26328 f.... npm
root 26470 f.... npm
root@host:/ fuser -k /var/lock/my_file_lock
/run/lock/my_file_lock: 4121 4122 4124 4153 4290 4430
root@host:/ ps -ef
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
...
root 4134 1 0 14:51 ? 00:00:00 sh -c node long_running_script.js
root 4135 4134 0 14:51 ? 00:00:08 node long_running_script.js
只会杀死顶级进程而npm却没有其孙子:
Form1 form1 = new Form1();
Form1 form2 = new Form2();
form1.Show();
form2.Show();
form2.Button1_Click += delegate {form2.textbox1.Text = form1.textbox1.Text};
答案 0 :(得分:0)
通常,您可以使用fuser -k
来终止锁文件打开的所有进程:
fuser -k /var/lock/my_lock_file
那就是说,Node非常有意地试图不将文件描述符传递给子进程。由于您正在使用NPM,因此您可能会尝试重复使用无论如何要传递的文件描述符。例如,要使用stdin:
exec 0<>/var/lock/my_lock_file
flock -x 0 || exit
# ...put the rest of your code here...
将传入stdin上的锁,因此只要原始stdin传递给子进程,这些进程就应该继承锁并被fuser
杀死。
如果stdin,stdout或stderr 不通过,我建议与上游聊天,查看特定的工具或流程是否通过,以查看是否存在&#39; sa避免或修改这种行为的方法。