如何在n秒内中止bash脚本

时间:2014-05-09 22:13:23

标签: bash

我想让我的脚本等待n秒,在此期间用户可以中止脚本。到目前为止我的代码看起来像这样

echo "Start Date provided :" $STARTDATE
echo "End date provided :" $ENDDATE
echo ""
echo "Please check the dates provided and in case of error press CTRL+C"
seq 1 15 |while read i; do echo -ne "\rWaiting for $i seconds"; sleep 1; done
echo ""
echo "Executing query on the remote side, please wait..."

当用户按下ctrl + c时,虽然发生了什么,while循环结束并继续执行脚本的其余部分。

如何让它中止整个脚本?提前感谢任何建议

3 个答案:

答案 0 :(得分:1)

我会使用陷阱

#!/bin/bash
trap 'echo -e "\nBye"; exit 1' INT

echo "Please check the dates provided and in case of error press CTRL+C"
seq 1 15 |while read i; do echo -ne "\rWaiting for $i seconds"; sleep 1; done
echo "Executing query on the remote side, please wait..."

答案 1 :(得分:0)

要抓住CTRL+C,您可以使用trap。例如:

#!/bin/bash
trap 'got_one' 2

got_one() {
 echo "I got one"
 exit 69
}

echo -e "PID: $$, PPID: $PPID" 
sleep 100

所以你的脚本看起来像这样:

#!/bin/bash
trap "interrupt" SIGINT

interrupt() {
  echo -e "\nExecution canceled."
  exit 69
}

countdown() {
  duration=$1 # in seconds
  seq $duration -1 0|while read i; do echo -ne "\rWaiting for $i seconds"; sleep 1; done
}

STARTDATE="foo"
ENDDATE="bar"

cat <<END
Start Date provided: $STARTDATE
  End date provided: $ENDDATE

Please check the dates provided and in case of error press CTRL+C
END

countdown 15

echo -e "\nExecuting query on the remote side, please wait..."

答案 2 :(得分:0)

这是一个更简单的程序,可以重现您的问题:

true | sleep 10  # Hit Ctrl-C here
echo "why does this execute?" 

问题是bash根据是否处理了SIGINT来确定是否继续脚本。它根据当前运行的进程是否被此信号杀死来确定是否处理了SIGINT。

由于seq打印其数字并立即成功退出,因此不会被SIGINT杀死。因此bash错误地认为信号已被处理,并且它继续运行。

您可以通过两种方式解决此问题:

  1. 添加退出脚本的SIGINT处理程序,无论信号是否处理完毕。
  2. 不要使用seq或其他任何可以立即退出的内容。
  3. 对于第一种方法,请参阅user3620917's answer

    第二种方法,

    for i in {15..1}
    do 
      printf '\rYou have %d seconds to hit Ctrl-C' "$i"
      sleep 1
    done