11

该问题适用于如下脚本:

脚本

#!/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进程。

4

2 回答 2

16

为陷阱编写一个陷阱,Ctrl+c并在陷阱中杀死所有子进程。把它放在你的wait命令之前。

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

trap handle_sigint SIGINT
于 2011-10-19T07:34:57.487 回答
0

一个简单的替代方法是使用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。

于 2014-02-07T14:16:31.250 回答