Bash:当脚本终止时,如何终止脚本的子进程?

发布于 2024-12-10 20:06:15 字数 549 浏览 0 评论 0原文

该问题适用于如下脚本:

脚本

#!/bin/sh

SRC="/tmp/my-server-logs"

echo "STARTING GREP JOBS..."
for f in `find ${SRC} -name '*log*2011*' | sort --reverse`
do
    (
        OUT=`nice grep -ci -E "${1}" "${f}"`
        if [ "${OUT}" != "0" ]
        then
            printf '%7s : %s\n' "${OUT}" "${f}"
        else
            printf '%7s   %s\n' "(none)" "${f}"
        fi
    ) &
done

echo "WAITING..."
wait

echo "FINISHED!"

当前行为

在控制台中按 Ctrl+C 会终止脚本,但不会终止已在运行的 grep 进程。

The question applies to a script such as the following:

Script

#!/bin/sh

SRC="/tmp/my-server-logs"

echo "STARTING GREP JOBS..."
for f in `find ${SRC} -name '*log*2011*' | sort --reverse`
do
    (
        OUT=`nice grep -ci -E "${1}" "${f}"`
        if [ "${OUT}" != "0" ]
        then
            printf '%7s : %s\n' "${OUT}" "${f}"
        else
            printf '%7s   %s\n' "(none)" "${f}"
        fi
    ) &
done

echo "WAITING..."
wait

echo "FINISHED!"

Current behavior

Pressing Ctrl+C in console terminates the script but not the already running grep processes.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

分開簡單 2024-12-17 20:06:15

Ctrl+c 编写一个陷阱,并在陷阱中杀死所有子进程。将其放在 wait 命令之前。

function handle_sigint()
{
    for proc in `jobs -p`
    do
        kill $proc
    done
}

trap handle_sigint SIGINT

Write a trap for Ctrl+c and in the trap kill all of the subprocesses. Put this before your wait command.

function handle_sigint()
{
    for proc in `jobs -p`
    do
        kill $proc
    done
}

trap handle_sigint SIGINT
梦里人 2024-12-17 20:06:15

一个简单的替代方案是使用 cat 管道。以下内容对我有用:

echo "-" > test.text; 
for x in 1 2 3; do 
    ( sleep $x; echo $x | tee --append test.text; ) & 
done | cat

如果我在最后一个数字打印到标准输出之前按 Ctrl-C。如果文本生成命令需要很长时间(例如“find /”),它也可以工作,即不仅通过 cat 到 stdout 的连接被杀死,而且实际上是子进程。

对于广泛使用子进程的大型脚本,确保缩进的 Ctrl-C 行为的最简单方法是将整个脚本包装到这样的子 shell 中,例如,

#!/usr/bin/bash
(
    ...
) | cat

我不确定这是否与安德鲁的答案具有完全相同的效果(即我'我不确定发送到子进程的信号是什么)。另外,我只使用 cygwin 进行了测试,而不是使用本机 Linux shell 进行了测试。

A simple alternative is using a cat pipe. The following worked for me:

echo "-" > test.text; 
for x in 1 2 3; do 
    ( sleep $x; echo $x | tee --append test.text; ) & 
done | cat

If I press Ctrl-C before the last number is printed to stdout. It also works if the text-generating command is something that takes a long time such as "find /", i.e. it is not only the connection to stdout through cat that is killed but actually the child process.

For large scripts that make extensive use of subprocesses the easiest way to ensure the indented Ctrl-C behaviour is wrapping the whole script into such a subshell, e.g.

#!/usr/bin/bash
(
    ...
) | cat

I am not sure though if this has the exactly same effect as Andrew's answer (i.e. I'm not sure what signal is sent to the subprocesses). Also I only tested this with cygwin, not with a native Linux shell.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文