对于许多例子trap使用trap ... INT TERM EXIT的清理任务。但是真的有必要列出所有三个 sigspecs 吗?
手册上说:
如果 SIGNAL_SPEC 为 EXIT (0),则在退出 shell 时执行 ARG。
我相信这适用于脚本是否正常完成或因为它收到SIGINT或SIGTERM. 一个实验也证实了我的信念:
$ cat ./trap-exit
#!/bin/bash
trap 'echo TRAP' EXIT
sleep 3
$ ./trap-exit & sleep 1; kill -INT %1
[1] 759
TRAP
[1]+ Interrupt ./trap-exit
$ ./trap-exit & sleep 1; kill -TERM %1
[1] 773
TRAP
[1]+ Terminated ./trap-exit
Run Code Online (Sandbox Code Playgroud)
那为什么这么多例子一一列举INT TERM EXIT呢?或者我错过了什么,有没有鞋底EXIT会错过的情况?
我正在尝试使用 Trap 创建一些错误报告来调用所有错误的函数:
Trap "_func" ERR
Run Code Online (Sandbox Code Playgroud)
是否有可能获得 ERR 信号是从哪条线路发送的?外壳是 bash。
如果我这样做,我可以阅读和报告使用了什么命令并记录/执行一些操作。
或者也许我在这一切都错了?
我测试了以下内容:
#!/bin/bash
trap "ECHO $LINENO" ERR
echo hello | grep "asdf"
Run Code Online (Sandbox Code Playgroud)
并且$LINENO正在返回 2. 不工作。
在使用set -e( errexit), set -u( nounset) 以及 ERR 和 EXIT 陷阱时,我观察到一些奇怪的行为。它们似乎相关,因此将它们放在一个问题中似乎是合理的。
set -u不触发 ERR 陷阱代码:
#!/bin/bash
trap 'echo "ERR (rc: $?)"' ERR
set -u
echo ${UNSET_VAR}
Run Code Online (Sandbox Code Playgroud)set -e不会改变结果set -eu在 EXIT 陷阱中使用退出代码是 0 而不是 1代码:
#!/bin/bash
trap 'echo "EXIT (rc: $?)"' EXIT
set -eu
echo ${UNSET_VAR}
Run Code Online (Sandbox Code Playgroud)set …如果我使用trap如在http://linuxcommand.org/wss0160.php#trap上描述的那样在退出之前捕获 ctrl-c(或类似的)和清理,那么我正在更改返回的退出代码。
现在这可能不会在现实世界中产生影响(例如,因为退出代码不可移植,而且在进程终止时的默认退出代码中讨论的那样并不总是明确的?)但我仍然想知道是否有真的没有办法阻止这种情况并返回中断脚本的默认错误代码吗?
示例(在 bash 中,但不应将我的问题视为特定于 bash 的问题):
#!/bin/bash
trap 'echo EXIT;' EXIT
read -p 'If you ctrl-c me now my return code will be the default for SIGTERM. ' _
trap 'echo SIGINT; exit 1;' INT
read -p 'If you ctrl-c me now my return code will be 1. ' _
Run Code Online (Sandbox Code Playgroud)
输出:
$ ./test.sh # doing ctrl-c for 1st read
If you ctrl-c me now my return code will be the …Run Code Online (Sandbox Code Playgroud) 我尝试了以下脚本:
#!/bin/bash
trap 'echo "touching a file" && touch $FILE' EXIT
foo1(){
echo "foo1"
}
foo(){
echo "foo"
export FILE=${FILE:-/tmp/file1}
}
(foo1)
foo
Run Code Online (Sandbox Code Playgroud)
上述脚本的输出是:
[root@usr1 my_tests]# ./test.sh
foo1
foo
touching a file
Run Code Online (Sandbox Code Playgroud)
但是,我希望在退出时foo1也调用 trap ,这在子shell中调用。
trap由子shell继承?trap由子shell继承?至少在GNU bash 版本 4.3.42 x86_64 && GNU bash 版本 4.3.11 x86_64 上发生
我使用sleep & wait $!而不是简单的sleep来获得sleep信号的可中断性(如SIGUSR1)。但是wait当您运行以下命令时,bash-builtin 的行为似乎很奇怪。
cat <(
trap 'echo SIGUSR1' SIGUSR1;
echo $BASHPID;
while :;do
sleep 1 &
wait $!;
echo test;
done
)&
Run Code Online (Sandbox Code Playgroud)
kill -10 /the pid of the subshell, printed by the previous command/
Run Code Online (Sandbox Code Playgroud)
^C (ctrl + C)
Run Code Online (Sandbox Code Playgroud)
然后,我得到了以 100% 消耗 CPU 的子外壳。
pkill -P $(pgrep -P $$)
Run Code Online (Sandbox Code Playgroud)
你知道为什么会发生这种行为吗?
注意 …
我正在运行下面的脚本以使用 lftp 从服务器自动下载文件。它可以工作,但在运行时我收到错误消息
trap: SIGINT: bad trap
Run Code Online (Sandbox Code Playgroud)
如果我用 INT 和 TERM 替换 SIGINT 和 SIGTERM 那么它确实有效,但我不知道它是否达到了同样的目的。这是在 Linux Debian 4.9.2-10 上。
#!/bin/sh
login="login"
pass="password"
host="server.server.com"
remote_dir='~/remote/dir'
local_dir="/local/dir"
base_name="$(basename "$0")"
lock_file="/tmp/$base_name.lock"
trap "rm -f $lock_file" SIGINT SIGTERM
if [ -e "$lock_file" ]
then
echo "$base_name is running already."
exit
else
touch "$lock_file"
/usr/bin/lftp -p 22 -u "$login","$pass" sftp://"$host" << EOF
set sftp:auto-confirm yes
set mirror:use-pget-n 5
mirror -c -P5 "$remote_dir" "$local_dir"
quit
EOF
rm -f "$lock_file"
trap - SIGINT SIGTERM
exit
fi
Run Code Online (Sandbox Code Playgroud) 我正在遵循有关如何使用 ssh-agent 设置无密码 SSH 身份验证的指南。
要启动 ssh-agent,作者建议在 中使用以下代码.bash_profile:
SSHAGENT=/usr/bin/ssh-agent
SSHAGENTARGS="-s"
if [ -z "$SSH_AUTH_SOCK" -a -x "$SSHAGENT" ]; then
eval `$SSHAGENT $SSHAGENTARGS`
trap "kill $SSH_AGENT_PID" 0
fi
Run Code Online (Sandbox Code Playgroud)
我不明白为什么它会捕获信号 0。根据man 7 signal没有这样的信号。
这只是一个错字或错误,还是真的有什么成就?
我知道你可以使用它在后台启动一个进程,而不会在进程被置于后台以及完成时收到通知:
(命令 &) &> /dev/null
但是,这会删除进程完成时捕获的选项 ( trap child_done CHLD)。
我怎么能两者兼得?