Ank*_*nna 6 command-line bash scripts
我试图script
在命令失败时执行。我们都知道,如果命令失败,则$?
值将不等于。如果命令失败,0
它会给出值127
。
脚本已准备就绪,但我无法捕获命令失败事件。
例如,如果我尝试一个不存在的命令,那么它必须接受该输入并将其传递给脚本。除了捕获失败的事件之外,我已经弄清楚了所有的逻辑。我怎样才能做到这一点?
Example
$-> code
Run Code Online (Sandbox Code Playgroud)
code 不是此处的命令,因此执行失败自动运行以下命令并将其code
作为cd
命令的输入。
cd code
Run Code Online (Sandbox Code Playgroud)
能做的就是使用函数。它们作为子 shell 运行,因此您可以通过重定向捕获一个子 shell 的错误,并将其发送到其他函数来处理。下面的脚本仅处理一个命令的失败。
#!/bin/bash
err_handling()
{
# grab command from output
cmd=$(awk -F ':' '{print $1}' < /dev/stdin)
# re-run with some proper argument
$cmd /dev/sda1
}
main()
{
# let main stop on error
# so note , last line won't run !!!
set -e
# This will fail with df: asdf: No such file or directory
# err_handling function will grab the command name
# and rerun it
df asdf
echo "Last line"
}
# Run main with redirecting stderr to stdout
# and original stdout to /dev/null. That way
# only stderr goes via pipe
main 2>&1 >/dev/null | err_handling
Run Code Online (Sandbox Code Playgroud)
awk
如果您告诉过滤输出,您可以处理多个命令。例如,这会读取 main 形式的所有 stderr,并针对每个 err 行提取命令。case...esac
用于处理特定的错误情况
#!/bin/bash
err_handling()
{
while read line
do
# grab command from output
cmd=$(awk -F ':' '{print $1}' <<< "$line" )
# re-run with some proper argument
case $line in
# do something with cmd depending on error
*not\ found*) echo "$cmd wasn't found" ;;
*No\ such\ file*) echo "$cmd didn't find your file" ;;
esac
done
}
main()
{
# let main stop on error
# so note , last line won't run if set -x is set !!!
# set -x
# This will fail with df: asdf: No such file or directory
# err_handling function will grab the command name
# and rerun it
df asdf
asdf
}
# Run main with redirecting stderr to stdout
# and original stdout to /dev/null. That way
# only stderr goes via pipe
main 2>&1 >/dev/null | err_handling
Run Code Online (Sandbox Code Playgroud)
请注意,正如我在评论中提到的 - 有些命令不使用 stderr,例如file
命令。在这种情况下,您需要重定向其标准输入并通过管道或其他方式处理它