BASH - 使用陷阱 ctrl+c

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12771909/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 22:48:42  来源:igfitidea点击:

BASH - using trap ctrl+c

bash

提问by mar_sanbas

I'm trying to execute commands inside a script using read, and when the user uses Ctrl+C, I want to stop the execution of the command, but not exit the script. Something like this:

我正在尝试使用 read 在脚本内执行命令,当用户使用Ctrl+ 时C,我想停止命令的执行,但不退出脚本。像这样的东西:

#!/bin/bash

input=
while [ "$input" != finish ]
do
    read -t 10 input
    trap 'continue' 2
    bash -c "$input"
done
unset input

When the user uses Ctrl+C, I want it to continue reading the input and executing other commands. The problem is that when I use a command like:

当用户使用Ctrl+ 时C,我希望它继续读取输入并执行其他命令。问题是当我使用如下命令时:

while (true) do echo "Hello!"; done;

It doesn't work after I type Ctrl+Cone time, but it works once I type it several times.

在我输入Ctrl+C一次后它不起作用,但是一旦我输入几次它就起作用。

回答by Gilles Quenot

Try the following code :

试试下面的代码:

#!/bin/bash
# type "finish" to exit

# function called by trap
other_commands() {
    printf "\rSIGINT caught      "
    sleep 1
    printf "\rType a command >>> "
}

trap 'other_commands' SIGINT

input="$@"

while true; do
    printf "\rType a command >>> "
    read input
    [[ $input == finish ]] && break
    bash -c "$input"
done

回答by cdarke

You need to run the command in a different process group, and the easiest way of doing that is to use job control:

您需要在不同的进程组中运行该命令,最简单的方法是使用作业控制:

#!/bin/bash 

# Enable job control
set -m

while :
do
    read -t 10 -p "input> " input
    [[ $input == finish ]] && break

    # set SIGINT to default action
    trap - SIGINT

    # Run the command in background
    bash -c "$input" &

    # Set our signal mask to ignore SIGINT
    trap "" SIGINT

    # Move the command back-into foreground
    fg %-

done