【问题标题】:How do you kill a running process in a bashscript without killing the script?如何在不终止脚本的情况下终止 bash 脚本中正在运行的进程?
【发布时间】:2020-10-03 02:20:35
【问题描述】:

如何在不终止脚本的情况下终止 bash 脚本中正在运行的进程?

目标

所以...我需要终止一个正在运行的进程才能继续执行我的脚本。

这是我的脚本的精简版:

# Setup
echo "Use ctrl+C to stop gathering data..."
./logger
#------------------
echo "Rest..."

我需要能够在不杀死我的脚本的情况下杀死 ./logger

预期与实际结果

我期待这样的结果:

Use ctrl+C to stop gathering data...
^C
Rest...

但是当我杀死程序时它会停止

use ctrl+C to stop gathering data...
^C

./logger 命令是一个 C 程序,它已经处理了SIGINT 信号 (Ctrl + C),但它在收到它之前不会停止。 有没有办法在不杀死我的脚本的情况下停止程序?

C 程序并不重要,但它看起来像这样

#include <stdio.h>
#include <signal.h>

int flag = 1;

void handler(int i)
{
     flag = 0;
}

int main(int argc, char** argv)
{
    signal(SIGINT, handler);
    while(flag)
    {
       usleep(10000);
    }
}

【问题讨论】:

  • 您应该使用sigaction 而不是signal,因为后者已被弃用。
  • @TedLyngmo 我不知道你的意思,但我在我的脚本中一次只运行一个命令。
  • 为什么./logger 行周围有括号?您是否有理由需要它在子 shell 中运行?
  • 更重要的问题:您是否在脚本顶部设置了-e 标志?
  • 尝试将 bash 脚本剥离到其基本要素。对于初学者,有一个只运行 C 程序的脚本,然后在下一行输入一个简单的命令,如 echo Check。看看这是否有效。你需要的是minimal reproducible example

标签: c bash shell sh


【解决方案1】:

如果您在运行脚本的终端上键入 control-C,则信号会发送到所有进程——记录器程序和脚本。并且脚本终止,因为您没有告诉它在记录器运行时忽略信号。您可以使用trap 命令执行此操作,但您需要在运行 C 程序之前撤消捕获。请参阅 Signals 上的 Bash 手册。

例如,我有一个程序dribbler 生成消息,默认情况下每秒一条,但它是可配置的。我将它用作您的./logger 程序的代理。 -m 选项指定消息; -n 选项要求对消息进行编号,-t 选项指定输出到标准输出(而不是默认写入的文件)。

#!/bin/bash
#
# SO 6418-0134

program="dribbler -t -n -m Hello"
echo "About to run '$program' command"

trap "" 2
(trap 2; $program)

echo "Continuing after '$program' exits"
sleep 1
echo "But not for long"

子shell是必需的。当我运行该脚本 (trapper.sh) 时,我得到例如:

$ bash trapper.sh
About to run 'dribbler -t -n -m Hello' command
0: Hello
1: Hello
2: Hello
3: Hello
^CContinuing after 'dribbler -t -n -m Hello' exits
But not for long
$

顺便说一句,POSIX 定义了一个命令logger,它使用syslog() 函数将消息写入syslog 守护进程。

也许还值得回顾一下关于Sending SIGINT to forked exec process which runs a script does not kill it 的问答,尤其是接受的答案及其在其他 Stack Exchange 网站上的问答链接,因为重要的是你和我都执行了 C 程序,而不是 shell 脚本。

【讨论】:

  • 如果您使用trap true 2,则不再需要子shell。
猜你喜欢
  • 2016-09-18
  • 2011-12-10
  • 2010-10-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-15
  • 2010-12-11
  • 2017-12-22
相关资源
最近更新 更多