我正在尝试从 bash 脚本中分离进程,以便在退出脚本时 SIGINT 不会被转发到该进程。
disown
我直接在终端中使用了该命令,但是在 bash 中,disown
并没有阻止 SIGINT 被转发。该脚本的目的是通过一次调用启动 openocd,然后启动 gdb。由于脚本永远不会退出(它正在运行 gdb),SIGINT 仍然从 gdb 转发到 openocd,这是一个问题,因为 SIGINT 用作 gdb 中的暂停命令。
在终端中它看起来像这样:
$ openocd & # run openocd demonized
$ disown $! # disown last pid
$ gdb # invoke GDB
当按此顺序在终端上调用时,SIGINT 不会从 gdb 传递到 openocd。但是,如果相同的调用是在 bash 脚本中,则会传递 SIGINT。
任何帮助将不胜感激。
ps 这个问题出现在 OS X 中,但我正在尝试使用也可移植到所有 Unix 工具的工具。
答案1
要将进程与 bash 脚本分离:
nohup ./process &
例如,如果您使用 (ctrl+c) 停止 bash 脚本SIGINT
,或者 shell 退出发送SIGHUP
,则该进程不会受到干扰,并将继续正常执行。stdout
&stderr
将被重定向到日志文件:nohup.out
.
如果您希望在执行独立命令的同时能够在终端中查看输出,请使用tail
:
TEMP_LOG_FILE=tmp.log
> "$TEMP_LOG_FILE"
nohup ./process &> "$TEMP_LOG_FILE" & tail -f "$TEMP_LOG_FILE" &
答案2
对我来说,这非常适合否认
command & disown
答案3
我找到的解决方案涉及一个名为“detach”的程序,由 Annon Inglorion 编写,可从他的网站下载网站
编译后,可以在脚本中使用它,如下所示:
$ ./detach -p debug.pid openocd <args> # detach openocd
$ gdb <args> # run gdb
$ kill -9 $(cat debug.pid) # end openocd process
$ rm debug.pid # remove file containing process id
第一行创建一个新进程(运行 openocd)并将进程 ID 存储在文件 (debug.pid) 中以供稍后使用。这可以防止奥利弗的回答中提供的 pid 的 grep 问题。退出下一个阻塞程序 (gdb) 时,存储 pid 的文件将用于直接终止分离的进程。
答案4
进程在后台正常运行、disown、nohup 等不会 100% 正常运行,因为子进程通常仍会因 SIGINT 等某些信号而死亡。您需要做的是使用不同的进程组:
#!/bin/bash
(set -m; child_process &)
while [ true ]; do
sleep 30
done
与使用 disown/nohup/whatever 不同,CTRL-C 和子进程将继续运行。