mirror of
https://github.com/LCTT/TranslateProject.git
synced 2025-01-28 23:20:10 +08:00
Merge pull request #19840 from wxy/20200629-Using-Bash-traps-in-your-scripts
PRF&PUB:20200629 Using Bash traps in your scripts
This commit is contained in:
commit
e667701b0a
@ -1,17 +1,18 @@
|
|||||||
[#]: collector: (lujun9972)
|
[#]: collector: (lujun9972)
|
||||||
[#]: translator: (HankChow)
|
[#]: translator: (HankChow)
|
||||||
[#]: reviewer: ( )
|
[#]: reviewer: (wxy)
|
||||||
[#]: publisher: ( )
|
[#]: publisher: (wxy)
|
||||||
[#]: url: ( )
|
[#]: url: (https://linux.cn/article-12715-1.html)
|
||||||
[#]: subject: (Using Bash traps in your scripts)
|
[#]: subject: (Using Bash traps in your scripts)
|
||||||
[#]: via: (https://opensource.com/article/20/6/bash-trap)
|
[#]: via: (https://opensource.com/article/20/6/bash-trap)
|
||||||
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
[#]: author: (Seth Kenlon https://opensource.com/users/seth)
|
||||||
|
|
||||||
在脚本中使用 Bash 信号捕获
|
在脚本中使用 Bash 信号捕获
|
||||||
======
|
======
|
||||||
|
|
||||||
> 无论你的脚本是否成功运行,<ruby>信号捕获<rt>trap</rt></ruby>都能让它平稳结束。
|
> 无论你的脚本是否成功运行,<ruby>信号捕获<rt>trap</rt></ruby>都能让它平稳结束。
|
||||||
|
|
||||||
![Hands programming][1]
|
![](https://img.linux.net.cn/data/attachment/album/202010/13/182135f2nktcrnryncisg8.jpg)
|
||||||
|
|
||||||
Shell 脚本的启动并不难被检测到,但 Shell 脚本的终止检测却并不容易,因为我们无法确定脚本会按照预期地正常结束,还是由于意外的错误导致失败。当脚本执行失败时,将正在处理的内容记录下来是非常有用的做法,但有时候这样做起来并不方便。而 [Bash][2] 中 `trap` 命令的存在正是为了解决这个问题,它可以捕获到脚本的终止信号,并以某种预设的方式作出应对。
|
Shell 脚本的启动并不难被检测到,但 Shell 脚本的终止检测却并不容易,因为我们无法确定脚本会按照预期地正常结束,还是由于意外的错误导致失败。当脚本执行失败时,将正在处理的内容记录下来是非常有用的做法,但有时候这样做起来并不方便。而 [Bash][2] 中 `trap` 命令的存在正是为了解决这个问题,它可以捕获到脚本的终止信号,并以某种预设的方式作出应对。
|
||||||
|
|
||||||
@ -19,22 +20,21 @@ Shell 脚本的启动并不难被检测到,但 Shell 脚本的终止检测却
|
|||||||
|
|
||||||
如果出现了一个错误,可能导致发生一连串错误。下面示例脚本中,首先在 `/tmp` 中创建一个临时目录,这样可以在临时目录中执行解包、文件处理等操作,然后再以另一种压缩格式进行打包:
|
如果出现了一个错误,可能导致发生一连串错误。下面示例脚本中,首先在 `/tmp` 中创建一个临时目录,这样可以在临时目录中执行解包、文件处理等操作,然后再以另一种压缩格式进行打包:
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
CWD=`pwd`
|
CWD=`pwd`
|
||||||
TMP=${TMP:-/tmp/tmpdir}
|
TMP=${TMP:-/tmp/tmpdir}
|
||||||
|
|
||||||
## create tmp dir
|
## create tmp dir
|
||||||
mkdir $TMP
|
mkdir "${TMP}"
|
||||||
|
|
||||||
## extract files to tmp
|
## extract files to tmp
|
||||||
tar xf "${1}" --directory $TMP
|
tar xf "${1}" --directory "${TMP}"
|
||||||
|
|
||||||
## move to tmpdir and run commands
|
## move to tmpdir and run commands
|
||||||
pushd $TMP
|
pushd "${TMP}"
|
||||||
for IMG in *.jpg; do
|
for IMG in *.jpg; do
|
||||||
mogrify -verbose -flip -flop $IMG
|
mogrify -verbose -flip -flop "${IMG}"
|
||||||
done
|
done
|
||||||
tar --create --file "${1%.*}".tar *.jpg
|
tar --create --file "${1%.*}".tar *.jpg
|
||||||
|
|
||||||
@ -42,22 +42,21 @@ tar --create --file "${1%.*}".tar *.jpg
|
|||||||
popd
|
popd
|
||||||
|
|
||||||
## bundle with bzip2
|
## bundle with bzip2
|
||||||
bzip2 --compress $TMP/"${1%.*}".tar \
|
bzip2 --compress "${TMP}"/"${1%.*}".tar \
|
||||||
--stdout > "${1%.*}".tbz
|
--stdout > "${1%.*}".tbz
|
||||||
|
|
||||||
## clean up
|
## clean up
|
||||||
/usr/bin/rm -r /tmp/tmpdir
|
/usr/bin/rm -r /tmp/tmpdir
|
||||||
```
|
```
|
||||||
|
|
||||||
一般情况下,这个脚本都可以按照预期执行。但如果归档文件中的文件是 PNG 文件而不是期望的 JPEG 文件,脚本就会在中途失败,这时候另一个问题就出现了:最后一步删除临时目录的操作没有被正常执行。如果你手动把临时目录删掉,倒是不会造成什么影响,但是如果没有手动把临时目录删掉,在下一次执行这个脚本的时候,就会在一个残留着很多临时文件的临时目录里执行了。
|
一般情况下,这个脚本都可以按照预期执行。但如果归档文件中的文件是 PNG 文件而不是期望的 JPEG 文件,脚本就会在中途失败,这时候另一个问题就出现了:最后一步删除临时目录的操作没有被正常执行。如果你手动把临时目录删掉,倒是不会造成什么影响,但是如果没有手动把临时目录删掉,在下一次执行这个脚本的时候,它必须处理一个现有的临时目录,里面充满了不可预知的剩余文件。
|
||||||
|
|
||||||
其中一个解决方案是在脚本开头增加一个预防性删除逻辑用来处理这种情况。但这种做法显得有些暴力,而我们更应该从结构上解决这个问题。使用 `trap` 是一个优雅的方法。
|
其中一个解决方案是在脚本开头增加一个预防性删除逻辑用来处理这种情况。但这种做法显得有些暴力,而我们更应该从结构上解决这个问题。使用 `trap` 是一个优雅的方法。
|
||||||
|
|
||||||
### 使用 `trap` 捕获信号
|
### 使用 trap 捕获信号
|
||||||
|
|
||||||
我们可以通过 `trap` 捕捉程序运行时的信号。如果你使用过 `kill` 或者 `killall` 命令,那你就已经使用过名为 `SIGTERM` 的信号了。除此以外,还可以执行 `trap -l` 或 `trap --list` 命令列出其它更多的信号:
|
我们可以通过 `trap` 捕捉程序运行时的信号。如果你使用过 `kill` 或者 `killall` 命令,那你就已经使用过名为 `SIGTERM` 的信号了。除此以外,还可以执行 `trap -l` 或 `trap --list` 命令列出其它更多的信号:
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
$ trap --list
|
$ trap --list
|
||||||
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
|
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
|
||||||
@ -85,40 +84,38 @@ $ trap --list
|
|||||||
|
|
||||||
例如,下面的这行语句可以捕获到在进程运行时用户按下 `Ctrl + C` 组合键发出的 `SIGINT` 信号:
|
例如,下面的这行语句可以捕获到在进程运行时用户按下 `Ctrl + C` 组合键发出的 `SIGINT` 信号:
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
`trap "{ echo 'Terminated with Ctrl+C'; }" SIGINT`
|
trap "{ echo 'Terminated with Ctrl+C'; }" SIGINT
|
||||||
```
|
```
|
||||||
|
|
||||||
因此,上文中脚本的缺陷可以通过使用 `trap` 捕获 `SIGINT`、`SIGTERM`、进程错误退出、进程正常退出等信号,并正确处理临时目录的方式来修复:
|
因此,上文中脚本的缺陷可以通过使用 `trap` 捕获 `SIGINT`、`SIGTERM`、进程错误退出、进程正常退出等信号,并正确处理临时目录的方式来修复:
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
CWD=`pwd`
|
CWD=`pwd`
|
||||||
TMP=${TMP:-/tmp/tmpdir}
|
TMP=${TMP:-/tmp/tmpdir}
|
||||||
|
|
||||||
trap \
|
trap \
|
||||||
"{ /usr/bin/rm -r $TMP ; exit 255; }" \
|
"{ /usr/bin/rm -r "${TMP}" ; exit 255; }" \
|
||||||
SIGINT SIGTERM ERR EXIT
|
SIGINT SIGTERM ERR EXIT
|
||||||
|
|
||||||
## create tmp dir
|
## create tmp dir
|
||||||
mkdir $TMP
|
mkdir "${TMP}"
|
||||||
tar xf "${1}" --directory $TMP
|
tar xf "${1}" --directory "${TMP}"
|
||||||
|
|
||||||
## move to tmp and run commands
|
## move to tmp and run commands
|
||||||
pushd $TMP
|
pushd "${TMP}"
|
||||||
for IMG in *.jpg; do
|
for IMG in *.jpg; do
|
||||||
mogrify -verbose -flip -flop $IMG
|
mogrify -verbose -flip -flop "${IMG}"
|
||||||
done
|
done
|
||||||
tar --create --file "${1%.*}".tar *.jpgh
|
tar --create --file "${1%.*}".tar *.jpg
|
||||||
|
|
||||||
## move back to origin
|
## move back to origin
|
||||||
popd
|
popd
|
||||||
|
|
||||||
## zip tar
|
## zip tar
|
||||||
bzip2 --compress $TMP/"${1%.*}".tar \
|
bzip2 --compress $TMP/"${1%.*}".tar \
|
||||||
--stdout > "${1%.*}".tbz
|
--stdout > "${1%.*}".tbz
|
||||||
```
|
```
|
||||||
|
|
||||||
对于更复杂的功能,还可以用 [Bash 函数][3]来简化 `trap` 语句。
|
对于更复杂的功能,还可以用 [Bash 函数][3]来简化 `trap` 语句。
|
||||||
@ -134,7 +131,7 @@ via: https://opensource.com/article/20/6/bash-trap
|
|||||||
作者:[Seth Kenlon][a]
|
作者:[Seth Kenlon][a]
|
||||||
选题:[lujun9972][b]
|
选题:[lujun9972][b]
|
||||||
译者:[HankChow](https://github.com/HankChow)
|
译者:[HankChow](https://github.com/HankChow)
|
||||||
校对:[校对者ID](https://github.com/校对者ID)
|
校对:[wxy](https://github.com/wxy)
|
||||||
|
|
||||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||||
|
|
Loading…
Reference in New Issue
Block a user