我正在Bash中编写一个脚本来测试一些代码。但是,如果编译代码一开始就失败了,那么运行测试似乎很愚蠢,在这种情况下,我将中止测试。
有没有一种方法,我可以这样做,而不包装整个脚本在一个while循环和使用中断?像是叮叮当当的后藤?
我正在Bash中编写一个脚本来测试一些代码。但是,如果编译代码一开始就失败了,那么运行测试似乎很愚蠢,在这种情况下,我将中止测试。
有没有一种方法,我可以这样做,而不包装整个脚本在一个while循环和使用中断?像是叮叮当当的后藤?
当前回答
如果您将使用source调用脚本,您可以使用return <x>,其中<x>将是脚本退出状态(使用非零值表示错误或false)。但是如果你调用一个可执行脚本(即直接使用它的文件名),return语句将导致一个抱怨(错误消息“return:只能从函数或源脚本中' return'”)。
如果使用exit <x>代替,当使用source调用脚本时,它将导致退出启动脚本的shell,但可执行脚本将如预期的那样终止。
要在同一个脚本中处理这两种情况,可以使用
return <x> 2> /dev/null || exit <x>
这将处理任何合适的调用。这是假设您将在脚本的顶层使用此语句。我建议不要直接从函数中退出脚本。
注意:<x>应该只是一个数字。
其他回答
使用set -e
#!/bin/bash
set -e
/bin/command-that-fails
/bin/command-that-fails2
脚本将在第一行失败后终止(返回非零退出代码)。在这种情况下,command-that-fails2将不会运行。
如果你要检查每一个命令的返回状态,你的脚本看起来像这样:
#!/bin/bash
# I'm assuming you're using make
cd /project-dir
make
if [[ $? -ne 0 ]] ; then
exit 1
fi
cd /project-dir2
make
if [[ $? -ne 0 ]] ; then
exit 1
fi
使用set -e,它看起来像:
#!/bin/bash
set -e
cd /project-dir
make
cd /project-dir2
make
任何失败的命令都将导致整个脚本失败,并返回一个退出状态,您可以使用$?如果你的脚本很长,或者你构建了很多东西,如果你到处添加返回状态检查,那就会很难看。
而不是if结构,你可以利用短路计算:
#!/usr/bin/env bash
echo $[1+1]
echo $[2/0] # division by 0 but execution of script proceeds
echo $[3+1]
(echo $[4/0]) || exit $? # script halted with code 1 returned from `echo`
echo $[5+1]
注意,由于交替运算符的优先级,必须使用一对括号。$? 是一个特殊变量,设置为退出最近调用的命令的代码。
我有同样的问题,但不能问,因为这将是一个重复。
当脚本稍微复杂一些时,使用exit的公认答案将不起作用。如果使用后台进程检查条件,exit只退出该进程,因为它在子shell中运行。要终止脚本,必须显式地终止它(至少这是我所知道的唯一方法)。
这里有一个关于如何做到这一点的小脚本:
#!/bin/bash
boom() {
while true; do sleep 1.2; echo boom; done
}
f() {
echo Hello
N=0
while
((N++ <10))
do
sleep 1
echo $N
# ((N > 5)) && exit 4 # does not work
((N > 5)) && { kill -9 $$; exit 5; } # works
done
}
boom &
f &
while true; do sleep 0.5; echo beep; done
这是一个更好的答案,但仍然不完整,我真的不知道如何摆脱boom部分。
一个SysOps的人曾经教过我三指爪技术:
yell() { echo "$0: $*" >&2; }
die() { yell "$*"; exit 111; }
try() { "$@" || die "cannot $*"; }
这些函数是*NIX OS和shell风味健壮的。把它们放在脚本的开头(bash或其他),try()你的语句和代码。
解释
(根据飞行绵羊的评论)。
大喊:打印脚本名称和所有参数到stderr: $0是脚本的路径; $*都是参数。 >&2表示>将标准输出重定向到&管道2。管道1本身就是标准输出。 Die的作用与yell相同,但是以非0的退出状态退出,这意味着“失败”。 try使用||(布尔OR),如果左边失败,它只计算右边。 $@又是所有的参数,但有所不同。
如果您将使用source调用脚本,您可以使用return <x>,其中<x>将是脚本退出状态(使用非零值表示错误或false)。但是如果你调用一个可执行脚本(即直接使用它的文件名),return语句将导致一个抱怨(错误消息“return:只能从函数或源脚本中' return'”)。
如果使用exit <x>代替,当使用source调用脚本时,它将导致退出启动脚本的shell,但可执行脚本将如预期的那样终止。
要在同一个脚本中处理这两种情况,可以使用
return <x> 2> /dev/null || exit <x>
这将处理任何合适的调用。这是假设您将在脚本的顶层使用此语句。我建议不要直接从函数中退出脚本。
注意:<x>应该只是一个数字。