如何从 bash 脚本中分离进程?

如何从 bash 脚本中分离进程?

我正在尝试从 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 和子进程将继续运行。

相关内容