![通过管道连接的 Shell 脚本:捕获一个脚本的终止](https://linux22.com/image/109852/%E9%80%9A%E8%BF%87%E7%AE%A1%E9%81%93%E8%BF%9E%E6%8E%A5%E7%9A%84%20Shell%20%E8%84%9A%E6%9C%AC%EF%BC%9A%E6%8D%95%E8%8E%B7%E4%B8%80%E4%B8%AA%E8%84%9A%E6%9C%AC%E7%9A%84%E7%BB%88%E6%AD%A2.png)
我有两个 shell 脚本,一个在服务器上运行并将一些文件写入临时目录。然后该目录作为 tar 存档发送到 stdout。最后(或者当它被中断时),应该删除临时目录。服务器脚本(例如保存在“~/get_dumps.sh”中)如下所示:
#!/bin/sh
set -e
temp_dir=`mktemp -d`
cd $temp_dir
trap "rm -r $temp_dir; exit" HUP INT TERM PIPE
for db in db1 db2 db3
do
pg_dump $db postgres > $db.sql
done
tar cJf - .
rm -r $temp_dir
使用以下脚本从客户端调用服务器脚本:
#!/bin/sh
set -e
temp_dir=`mktemp -d`
trap "rm -r $temp_dir; exit" HUP INT TERM PIPE
mkdir /tmp/dumps
ssh server '~/get_dumps.sh' | tar xJf - -C $temp_dir
ls $temp_dir
rm -r $temp_dir
如果我运行客户端脚本并按 Ctrl-C,则客户端和服务器上的临时目录都不会被删除。为什么trap
这里不起作用?
编辑:首先我忘记添加set -e
.
答案1
问题是set -e
。如果在多个命令通过管道连接在一起时按下 Ctrl-c,SIGINT 不会发送到脚本,而是发送到其他地方。这会产生一个错误,该错误由 处理set -e
,因此脚本直接退出。要在带有管道的脚本中使用set -e
可靠,还必须捕获EXIT
:
#!/bin/sh
set -e
temp_dir=`mktemp -d`
cd $temp_dir
trap "rm -r $temp_dir; exit" HUP INT TERM PIPE EXIT
for db in db1 db2 db3
do
pg_dump $db postgres > $db.sql
done
tar cJf - .
在这种情况下,法线也exit
由陷阱处理,这在许多情况下无论如何都是有用的。