Hen*_*son 8 scripting bash signals trap
假设我有一个 bash 脚本:
while :
do
foo
done
Run Code Online (Sandbox Code Playgroud)
我希望能够从控制台运行此脚本并能够在任意时间退出它,只要它发生在两次 foo 运行之间。因此,如果说,我按Ctrl+ C(这可能是导致脚本退出的另一个操作,Ctrl+C只是一个示例),它将在执行 foo 后在下一个可用点退出:
while :
do
foo
if [pressed_ctrl_c]:
break
done
Run Code Online (Sandbox Code Playgroud)
您可以尝试这种构造:
#!/bin/bash
#
INTR=
trap 'INTR=yes; echo "** INTR **" >&2' INT
while :
do
(
# Protect the subshell block
trap '' INT
# Protected code here
echo -n "The date/time is: "
sleep 2
date
read -t2 -p 'Continue (y/n)? ' YN || echo
test n = "$YN" && echo "Asked for BREAK" >&2 && exit 90
)
SS=$?
test 90 -eq $SS && echo "Matched BREAK" >&2 && break
# Ctrl/C, perhaps?
test yes = "$INTR" && echo "Matched INTR" >&2 && break
done
exit 0
Run Code Online (Sandbox Code Playgroud)
一些笔记
read和test一对演示交互式控制到内部受保护的代码段( ... )块。exit 90是相当于break而是从一个子shell里。该test 0 != $? ...子shell块结束后立即行有没有捕捉exit 90状态和执行break的代码其实是想。break,exit,等...)gdb为SIGINT( CtrlC)安装自己的处理程序。如果目的是防止用户中断会话,更改中断键可能有助于混淆情况(请参阅下面的代码)。不优雅但可能有效。更改终端上的 SIGINT 密钥
G=$(stty -g) # Save settings
test -n "$G" && stty intr ^A # That is caret and A, not Ctrl/A
# ... SIGINT generated with Ctrl/A rather than Ctrl/C ...
test -n "$G" && stty "$G" # Restore original settings
Run Code Online (Sandbox Code Playgroud)