我本质上是试图实现一个函数,它断言另一个命令的失败(非零退出代码),并在失败时打印一条消息.
这是我的功能:
function assert_fail () {
COMMAND=$@
if [ `$COMMAND; echo $?` -ne 0 ]; then
echo "$COMMAND failed as expected."
else
echo "$COMMAND didn't fail"
fi
}
# This works as expected
assert_fail rm nonexistent
# This works too
assert_fail rm nonexistent nonexistent2
# This one doesn't work
assert_fail rm -f nonexixtent
Run Code Online (Sandbox Code Playgroud)
只要我向命令添加选项,它就不起作用.以下是上述输出:
rm: cannot remove `nonexistent': No such file or directory
rm nonexistent failed as expected.
rm: cannot remove `nonexistent': No such file or directory
rm: cannot remove `nonexistent2': No such file or directory
rm nonexistent nonexistent2 failed as expected.
rm -f nonexistent didn't fail
Run Code Online (Sandbox Code Playgroud)
我试过在命令周围加双引号,但没有用.我希望上面的第三次调用产生与其他两种相似的输出.
我感谢任何/所有的帮助!
@rici正确地指出了你所看到的问题,但你的包装函数存在一些实际问题.首先,它没有在参数中正确保留空格(以及其他一些有趣的字符).COMMAND=$@(或COMMAND="$@")将所有参数合并为一个字符串,从而失去参数与参数内空格之间的区别.要保持它们直接,要么"$@"直接使用而不将其存储在变量中,要么将其存储为数组(COMMAND=("$@")然后执行它"${COMMAND[@]}").其次,如果命令将任何内容输出到stdout,它将对您的退出状态检查造成严重破坏; 正如@chepner所说,直接测试它.这是我建议的重写:
function assert_fail () {
if "$@"; then
echo "$* didn't fail"
else
echo "$* failed as expected."
fi
}
Run Code Online (Sandbox Code Playgroud)
请注意,我执行echo命令的方式确实失去了参数中空格的区别.如果这是一个问题,请将echo命令替换为:
printf "%q " "$@"
echo "didn't fail"
Run Code Online (Sandbox Code Playgroud)
和
printf "%q " "$@"
echo "failed as expected."
Run Code Online (Sandbox Code Playgroud)
rm -f永远不会在不存在的文件上失败.它与你的包装器无关.见man rm:
OPTIONS
-f, --force
ignore nonexistent files, never prompt
Run Code Online (Sandbox Code Playgroud)