我有一个调用许多命令的Bash shell脚本.如果任何命令返回非零值,我希望shell脚本自动退出,返回值为1.
如果没有明确检查每个命令的结果,这可能吗?
例如
dosomething1
if [[ $? -ne 0 ]]; then
exit 1
fi
dosomething2
if [[ $? -ne 0 ]]; then
exit 1
fi
Run Code Online (Sandbox Code Playgroud) 可能重复:
出错时自动退出bash shell脚本
如何在第一次命令失败时停止bash,而不是在我的代码中放入这样的东西?
some_prog || exit 1
some_other_prog || exit 1
Run Code Online (Sandbox Code Playgroud) 我想在Bash脚本中引发错误,消息"Test cases Failed !!!".在Bash中如何做到这一点?
例如:
if [ condition ]; then
raise error "Test cases failed !!!"
fi
Run Code Online (Sandbox Code Playgroud) 我几乎没有开始使用Jenkins,这是我到目前为止遇到的第一个问题.基本上我的jenkins工作总是成功,即使在某些测试中发生了错误.这就是我在shell配置中运行的内容:
bundle install
rake db:migrate:reset
rake test:units
rake spec:models
Run Code Online (Sandbox Code Playgroud)
事情是Jenkins只报告失败的任务是最后一个失败.例如,如果我将"rake test:units"放在最后一个任务中,它会在出现问题时通知错误.使用此配置我只获得rspec测试的错误报告,但不获取单元测试的错误报告.
有人想知道为什么我不仅使用rspec或单元测试,我们目前正在迁移到rspec,但这个问题仍然很痛苦.
这是来自Jenkinsm的日志的一部分,因为你可以看到其中一个单元测试失败但jenkins仍然成功完成.
314 tests, 1781 assertions, 1 failures, 0 errors, 0 skips
rake aborted!
Command failed with status (1): [/var/lib/jenkins/.rvm/rubies/ruby-1.9.3-p1...]
Tasks: TOP => test:units
(See full trace by running task with --trace)
Lot of rspec tests here....
Finished in 3.84 seconds
88 examples, 0 failures, 42 pending
Pushing HEAD to branch master of origin repository
Pushing HEAD to branch master at repo origin
Finished: SUCCESS
Run Code Online (Sandbox Code Playgroud) 根据这个接受的答案使用set -e内置应该足以让bash脚本退出第一个错误.然而,以下脚本:
#!/usr/bin/env bash
set -e
echo "a"
echo "b"
echo "about to fail" && /bin/false && echo "foo"
echo "c"
echo "d"
Run Code Online (Sandbox Code Playgroud)
打印:
$ ./foo.sh
a
b
about to fail
c
d
Run Code Online (Sandbox Code Playgroud)
删除echo "foo" 确实会停止脚本; 但为什么?
在Ruby脚本中,有多种方法可以调用系统命令/命令行
`command arg1 arg2`%x(command arg1 arg2)(可用的其他分隔符)Kernel#system 方法: system('command arg1 arg2')Kernel#exec 方法: exec('command arg1 arg2')如果我希望Ruby脚本在被调用的命令失败时(异常)失败(使用非零退出代码),我可以检查$?前两个变量的特殊变量中的退出代码:
`command arg1 arg2`
fail unless $? == 0
Run Code Online (Sandbox Code Playgroud)
要么
%x,command arg1 arg2,
fail unless $? == 0
Run Code Online (Sandbox Code Playgroud)
如果我对命令的标准输出转到Ruby脚本的标准输出(我是),我可以使用变量3并检查其返回值:
unless system('command arg1 arg2')
fail
end
Run Code Online (Sandbox Code Playgroud)
如果我不关心拯救异常的能力,也不关心无法解决的异常的堆栈跟踪打印行为,我当然可以使用exit(1)或者在前两个变体exit($?)中代替fail.
如果进一步执行命令是Ruby脚本应该做的最后一件事,即使命令成功(退出代码0),我也可以使用第四个变体:
exec('command arg1 arg2')
Run Code Online (Sandbox Code Playgroud)
这将使用通过调用命令创建的新进程替换Ruby进程,但Ruby脚本的调用者的效果将是相同的:如果被调用的命令导致非零退出,他会看到非零退出代码码.
我非常喜欢第四个变体的简洁性,但是如果执行命令不是最后一件事,如果成功,我很遗憾不会使用它.相比之下,其他变体的条件fail或exit调用看起来非常不洁净,并且在我的一个用例中,往往违反单一抽象级别和单一责任原则.
我当然可以轻松地为前三种方法中的任何一种编写一个包装函数,使它们的用法看起来简洁,但由于这看起来像是一个基本的操作方法,我想知道Ruby是否已经内置了类似的内容 ......是一个我可以使用的实用程序函数,而不是我自己的包装器,或者一种机制,当命令失败时,它会改变一个或多个命令调用方法的行为,导致错误或非零退出,类似于sh和bash的选择set -e.
我经常在 dockerfiles 中看到set -e或set -ex,我想知道它们的目的是什么。最近,我也看到了set -o pipefail,我不知道它是做什么的。我试图man set看看是否有任何手册描述,但没有任何描述,我在这里求助。