我尝试script
在命令失败时执行。我们都知道,如果命令失败,$?
值将不等于。如果命令失败,它 0
会给出值。127
脚本已准备好,但我无法捕获命令失败事件。
例如,如果我尝试一个不存在的命令,那么它必须接受该输入并将其传递给脚本。除了捕获失败事件外,我已经弄清楚了所有逻辑。我该怎么做?
Example
$-> code
代码不是这里的命令,因此执行失败,请自动运行以下命令并将其code
作为cd
命令的输入。
cd code
答案1
可以做的是使用函数。它们作为子 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
如果您告诉过滤输出,则可以处理多个命令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
注意,正如我在评论中提到的那样 - 有些命令不使用 stderr,例如file
命令。在这种情况下,您需要重定向其 stdin 并通过管道或其他方式处理它