英文:
Trap and SIGINT in bash
问题
#!/bin/bash
count=0
for i in 'seq 1 5';
do
trap ctrl_c SIGINT
((count=count+1))
done
echo $count
这是您提供的脚本。您希望在用户使用Ctrl+C的次数达到5次时才允许用户退出。然而,脚本中存在一些问题。首先,'seq 1 5'
应该是反引号(`seq 1 5`
),以便执行seq 1 5
命令。其次,trap
命令需要指定要执行的函数,但在脚本中并没有定义 ctrl_c
函数。以下是修复后的脚本示例:
#!/bin/bash
count=0
# 定义 ctrl_c 函数
ctrl_c() {
((count=count+1))
if [ $count -eq 5 ]; then
exit 0
fi
}
for i in `seq 1 5`;
do
trap ctrl_c SIGINT
done
# 无限循环以等待用户的 Ctrl+C 输入
while true; do
sleep 1
done
此脚本会在用户第5次按下Ctrl+C时退出。
英文:
I am creating a script, using trap, that will count the number of times a user uses ctrl_c and then allows the user to finally quit on the 5th attempt.
#!/bin/bash
count=0
for i in 'seq 1 5';
do
trap ctrl_c SIGINT
((count=count+1))
done
echo $count
Not sure if I am on the right track for this one. Or if I am using trap with SIGINT correctly. When I run this script I just get 1. I do not get the option to try ^C multiple times.
答案1
得分: 1
我想我明白你不理解trap
的问题。以下是使用你的代码的示例。
有一些关于trap
如何工作的文章在StackOverflow上,例如:https://stackoverflow.com/questions/14197470/how-does-trap-kill-work-in-bash-on-linux
trap
在这里有描述:https://www.gnu.org/savannah-checkouts/gnu/bash/manual/html_node/Bourne-Shell-Builtins.html
在GitHub上也有很多使用它的示例。如果我的示例不够清楚,希望其中一个对你有帮助。https://github.com/search?q=trap+SIGINT+language%3AShell&type=code&ref=advsearch
我认为cleanup
的示例最有帮助。
#/bin/bash
ctrl_c() {
((count=count+1))
[[ count == 5 ]] && (
echo $count
exit
)
}
count=0
trap ctrl_c SIGINT
# 做一些事情
英文:
I think I see the issue you are having understanding trap
. Below is an example using your code.
There are a few articles about how trap
works here on StackOverflow. For example https://stackoverflow.com/questions/14197470/how-does-trap-kill-work-in-bash-on-linux
trap
is described here https://www.gnu.org/savannah-checkouts/gnu/bash/manual/html_node/Bourne-Shell-Builtins.html
There are many examples of its use on GitHub too. I hope one of them helps if my example isn't clear. https://github.com/search?q=trap+SIGINT+language%3AShell&type=code&ref=advsearch
I think the cleanup
examples are most helpful.
#/bin/bash
ctrl_c() {
((count=count+1))
[[ count == 5 ]] && (
echo $count
exit
)
}
count=0
trap ctrl_c SIGINT
# do stuff
</details>
# 答案2
**得分**: 0
以下是您要翻译的内容:
No, it's `trap [-lp] [[arg] sigspec]` per [man 1 bash](https://www.man7.org/linux/man-pages/man1/bash.1.html) (or think of it as `trap command_to_run signal[s]`) So can set 2 `trap` instructions to count the <kbd>Ctrl+C</kbd> `SIGINT` signals and then to print `count` when the program terminates, (1) a `trap` for <kbd>Ctrl+C</kbd> to catch `SIGINT`and (2) to handle exit or termination (signals `EXIT` and `SIGTERM`) to output `count` at the end. (see [man 7 signal](https://man7.org/linux/man-pages/man7/signal.7.html) for available signals and corresponding numbers or just type `trap -l` at the command line)
The `-l` option causes the shell to print a list of the signal names and numbers (try it `trap -l` at the command line) and `-p` options allow you to display the list of commands associated with a `sigspec`.
You can actually do something like the following where you just loop continually with `read` and a timeout, handing `'q'` to quit and relying on your `SIGINT` `trap` to increment the counter, e.g.
```bash
#!/bin/bash
declare -i count=0 ## may as well declare count as int type
## define 2 trap actions, one for script termination or exit
# and one to increment count on Ctrl+C
trap 'printf "count: %d\n" "$count"' SIGTERM EXIT
trap 'count=$((count + 1))' SIGINT
## output simple directions to tell the user what to do
printf "type 'q' to quit or Ctrl+C to increment count\n"
while : ## loop continually
do
read -r -s -N 1 -t 1 resp; ## read into resp with 1 sec timeout
[ "$resp" = q ] && break ## if 'q' entered, break loop
done
(of course, you can simply output count
after you exit the loop, but setting two trap
instructions provides an additional way to handle it and demonstrates setting multiple traps)
Example Use/Output
Where we hit <kbd>Ctrl+C</kbd> 5 times before pressing 'q'
,
$ bash trapcount.sh
type 'q' to quit or Ctrl+C to increment count
count: 5
See What Is Happening
You can also write a simple function that is used as the trap
action that will indicate <kbd>Ctrl+C</kbd> was pressed and provide the current count
. For example:
#!/bin/bash
declare -i count=0 ## may as well declare count as int type
increment_count() { ## simle function to use as trap action
count=$((count + 1)) ## incement and output count
printf "Ctrl+C handled, count: %d\n" "$count"
}
## define 2 trap actions, one for script termination or exit
# and one to increment count on Ctrl+C
trap 'printf "count: %d\n" "$count"' SIGTERM EXIT
trap increment_count SIGINT
## output simple directions to tell the user what to do
printf "type 'q' to quit or Ctrl+C to increment count\n"
while : ## loop continually
do
read -r -s -N 1 -t 1 resp; ## read into resp with 1 sec timeout
[ "$resp" = q ] && break ## if 'q' entered, break loop
done
Example Use/Output
Same 5 <kbd>Ctrl+C</kbd> before 'q'
:
$ bash trapcount2.sh
type 'q' to quit or Ctrl+C to increment count
Ctrl+C handled, count: 1
Ctrl+C handled, count: 2
Ctrl+C handled, count: 3
Ctrl+C handled, count: 4
Ctrl+C handled, count: 5
count: 5
That provides a bit better feedback.
Let me know if you have questions.
英文:
No, it's trap [-lp] [[arg] sigspec]
per man 1 bash (or think of it as trap command_to_run signal
) So can set 2 trap
instructions to count the <kbd>Ctrl+C</kbd> SIGINT
signals and then to print count
when the program terminates, (1) a trap
for <kbd>Ctrl+C</kbd> to catch SIGINT
and (2) to handle exit or termination (signals EXIT
and SIGTERM
) to output count
at the end. (see man 7 signal for available signals and corresponding numbers or just type trap -l
at the command line)
The -l
option causes the shell to print a list of the signal names and numbers (try it trap -l
at the command line) and -p
options allow you to display the list of commands associated with a sigspec
.
You can actually do something like the following where you just loop continually with read
and a timeout, handing 'q'
to quit and relying on your SIGINT
trap
to increment the counter, e.g.
#!/bin/bash
declare -i count=0 ## may as well declare count as int type
## define 2 trap actions, one for script termination or exit
# and one to increment count on Ctrl+C
trap 'printf "count: %d\n" "$count"' SIGTERM EXIT
trap 'count=$((count + 1))' SIGINT
## output simple directions to tell the user what to do
printf "type 'q' to quit or Ctrl+C to increment count\n"
while : ## loop continually
do
read -r -s -N 1 -t 1 resp; ## read into resp with 1 sec timeout
[ "$resp" = q ] && break ## if 'q' entered, break loop
done
(of course, you can simply output count
after you exit the loop, but setting two trap
instructions provides an additional way to handle it and demonstrates setting multiple traps)
Example Use/Output
Where we hit <kbd>Ctrl+C</kbd> 5 times before pressing 'q'
,
$ bash trapcount.sh
type 'q' to quit or Ctrl+C to increment count
count: 5
See What Is Happening
You can also write a simple function that is used as the trap
action that will indicate <kbd>Ctrl+C</kbd> was pressed and provide the current count
. For example:
#!/bin/bash
declare -i count=0 ## may as well declare count as int type
increment_count() { ## simle function to use as trap action
count=$((count + 1)) ## incement and output count
printf "Ctrl+C handled, count: %d\n" "$count"
}
## define 2 trap actions, one for script termination or exit
# and one to increment count on Ctrl+C
trap 'printf "count: %d\n" "$count"' SIGTERM EXIT
trap increment_count SIGINT
## output simple directions to tell the user what to do
printf "type 'q' to quit or Ctrl+C to increment count\n"
while : ## loop continually
do
read -r -s -N 1 -t 1 resp; ## read into resp with 1 sec timeout
[ "$resp" = q ] && break ## if 'q' entered, break loop
done
Example Use/Output
Same 5 <kbd>Ctrl+C</kbd> before 'q'
:
$ bash trapcount2.sh
type 'q' to quit or Ctrl+C to increment count
Ctrl+C handled, count: 1
Ctrl+C handled, count: 2
Ctrl+C handled, count: 3
Ctrl+C handled, count: 4
Ctrl+C handled, count: 5
count: 5
That provides a bit better feedback.
Let me know if you have questions.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论