bash: exit script loop
I am using zgrep - a bash script wrapper that runs grep on compressed files.
The problem is that control-c won't stop the script. I guess the reason is that the loop over the files, spawns sub-shells, so the terminate signal goes to the running grep process, and not to the parent script. So even trap in the parent script does not work.
to illustrate:
trap break SIGPIPE SIGTERM SIGQUIT SIGSTOP
for i
gzip -cdfq "$i" | grep $pattern
done
I also tried "/bin/kill -- -$$"
instead of break
, with the same results. I gues开发者_StackOverflows the script does not get the interrupt.
Any idea how I can solve this?
I am surprised your C-c does not work (you might want to look into stty
). Nevertheless there are several problems with your script.
- The
trap
command should also stop onSIGINT
. - The
break
in the trap will not get you out of the loop. You'll need something like:
DONE= trap 'DONE=1' SIGINT for i in "$@"; do [[ -n $DONE ]] && break ∶
Per the bash
info documentation:
If Bash is waiting for a command to complete and receives a signal for which a trap has been set, the trap will not be executed until the command completes.
You'll need to write a wrapper in something that gives you more control over signals if you want to change that.
I'm getting similar behavior by trap (not getting executed). My environment is ksh88
on HP Unix
. My trap is to catch INT KILL
and QUIT
. I'm calling gzip
within a shell function. If I remove gzip
the trap handler gets executed when I send interrupt signal to it but not when I have gzip
.
Regarding your problem: The reason that Cntrl-C
won't stop your loop is because you are catching it by your trap. And your trap handler is not correct command to stop your loop. Your parent script won't get stop neither as it doesn't see any signal, again because by 'trap' you are saying that you want to handle it not the shell. If you want to just exit the loop then put your loop in a separate function and set the trap in that function. Just to give you an idea, here is a.ksh
:
function f1
{
trap return INT QUIT KILL
i=0
while [[ $i -lt 100 ]]
do
$(( i=$i+1 ))
sleep 2
echo $i
done
}
echo BEFORE calling f1
f1
echo AFTER calling f1
Testing a.ksh:
$ a.ksh
BEFORE calling f1
1
2
3
AFTER calling f1
I hit Contrl-C
after the third iteration. As you see I got AFTER calling f1
message which means contrl-C
just stopped the function not the entire process (a.ksh
). Hope that helped.
精彩评论