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


18

我正在尝试从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工具都可移植的工具。


nohup不是一个正确的答案。您应该添加一些伪代码或示例代码,以更精确地显示所需的内容。
Bruce Ediger

1
您愿意使用类似的工具screen吗?
埃里克·雷诺夫

Answers:


17

要从bash脚本中分离进程:

nohup ./process &

如果使用SIGINT(ctrl + c)停止bash脚本,或者外壳退出SIGHUP例如发送,该过程将不会受到困扰,并且将继续正常执行。stdoutstderr将被重定向到日志文件:nohup.out

如果希望在终端中看到输出的同时执行分离的命令,请使用tail

TEMP_LOG_FILE=tmp.log
> "$TEMP_LOG_FILE"
nohup ./process &> "$TEMP_LOG_FILE" & tail -f "$TEMP_LOG_FILE" &

为什么是nohup必要的?是什么区别nohup COMMAND &COMMAND &如果你的目标仅仅是在后台运行命令,并释放终端?
詹姆士·维尔兹巴

@JamesWierzba的区别之一是,如果即使退出shell后仍需要命令继续运行,则nohup是必经之路。网络上有成千上万的详尽解释。例如stackoverflow.com/questions/15595374/…–
marc


4

我找到的解决方案涉及一个由Annon Inglorion编写的名为“ detach”的程序,可以从他的网站下载该程序。

编译后,可以在脚本中使用它,如下所示:

$ ./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)中,以备后用。这样可以避免Oliver的答案中提供的pid的grepping问题。退出下一个阻止程序(gdb)后,将使用存储pid的文件直接杀死分离的进程。


可以确认,detach创造奇迹。
AS

2

一个简单且可移植的解决方案:

echo "openocd" | at now #openocd starts now, but via the at daemon, not the current shell!
pid=$(ps -ef | grep "[o]penocd" | awk '{print $1}')  
echo "openocd is running with pid: $pid"
gdb

一些可移植性警告:ps选项取决于操作系统!您可以使用:的变体{ ps -ef || ps aux ;} | grep '[o]penocd | cut -f 1at无法使用(很奇怪,但这会发生...)。$(...)需要一个不太旧的外壳,否则请使用反引号。


这似乎很危险,如果多个进程以相同的名称运行,或者甚至另一个进程包含单词openocd,则对pid进行grepping可能会发生意外的事情。
Orion

1
@orion:我举一个简单的例子给出想法,您提到的那些问题很容易消除:at启动一个脚本来启动程序,并在文件中给出其pid,然后让主脚本等待文件出现,然后从中读取pid。
奥利维尔·杜拉克

当然,您应该在我的(过于简单的)示例中用awk内的测试替换grep,在右列(通常为$ 8)(这些列取决于您的操作系统和ps的版本/选项)
Olivier Dulac
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.