如何在 n 秒内中止 bash 脚本 [重复]

Posted

技术标签:

【中文标题】如何在 n 秒内中止 bash 脚本 [重复]【英文标题】:How to abort a bash script in n seconds [duplicate] 【发布时间】:2014-06-27 19:00:12 【问题描述】:

我想让我的脚本等待 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 循环结束并继续执行脚本的其余部分。

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

【问题讨论】:

一种方法是为 SIGINT 注册一个信号处理程序。我不知道这是否过于复杂。 为什么是while循环?只需sleep x 秒。按下 CTRL+C 后,脚本将终止。 这是BashFAQ #68,这是本网站上一个非常非常常见的问题(显然是由于人们没有查看常见问题解答)。 你应该接受带有绿色勾号的正确答案,记住你也可以投票给更多好的答案。 【参考方案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..."

【讨论】:

谢谢!试过了,快速简单的解决方案【参考方案2】:

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

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

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

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

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

    添加一个 SIGINT 处理程序,该处理程序会退出您的脚本,无论信号是否已被处理。 不要使用 seq 或其他任何会立即退出的内容。

对于第一种方法,请参阅user3620917's answer。

第二种方法,

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

【讨论】:

感谢您的回复,除了解决方案之外,我真的很喜欢您的见解!【参考方案3】:

要捕获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..."

【讨论】:

对于函数参数,您可以使用$1 而不将其分配给另一个变量,但是我发现命名它们是一个好习惯,这样便于以后阅读

以上是关于如何在 n 秒内中止 bash 脚本 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

Bash-Shell 脚本中止没有错误

如何在bash脚本中传递两个参数或参数[重复]

如何使用 bash -c 调用 bash 脚本函数 [重复]

考虑到它的参数,如何检测bash脚本是不是已经在运行[重复]

如何在bash脚本中运行curl并将结果保存在变量中[重复]

如何在bash脚本中通过函数调用将参数/参数从一个函数传递到另一个函数[重复]