在bash中用双括号执行命令不起作用

时间:2014-02-10 15:52:57

标签: linux bash shell

为了保持一致,我试图在所有if语句中使用双括号[[]]。但是当我要检查我想要运行的命令的返回值时,我确实遇到了问题。在测试了几种创建if语句的方法后,我发现只有没有括号才能执行命令。

以下不起作用:

if [[ $command ]] ; then
    echo "something"
fi

if [[ $(command) ]] ; then
    echo "something"
fi

if [[ ${command} ]] ; then
    echo "something"
fi

并且上面的代码即使在没有运行命令时也使if循环成立。 由于上面的代码不适用于大括号,因此无法使用它:

[[ $command ]] || echo "failed"

并且它在子shell中也不起作用。

以下作品:

if $command ; then
    echo "something"
fi

if $(command) ; then
    echo "something"
fi

为什么在带有括号的if循环中放置一个命令是不行的,为什么上面的if循环在它甚至没有运行命令时报告为真?我正在使用bash 4.1.9版。我已经尝试了很多次,if循环就像我上面输入的那样简单,它只是检查一个命令是否成功运行并退出,如果它不是。

3 个答案:

答案 0 :(得分:3)

简短的回答是:

  • [[[期待表达式

  • if需要命令

话说:

[[ $(command) ]]

基本上会执行:

[[ -n <command_output> ]]

可能是也可能不是你想要的。另一方面,说:

$command && echo something || echo other

将根据命令的返回码(something和非零值)回显other0

答案 1 :(得分:1)

双括号是test的快捷方式。在您的示例中,正在发生的是您正在测试shell变量$命令是否存在。

if [[ $PWD ]]; then
    echo PWD is set to a value
fi

if [[ $NOT_A_REAL_VAR ]]; then
    echo Nope, its not set
fi

在第二个示例中,您正在使用命令替换来检查command输出标准输出上的内容。

if [[ $(echo hi) ]]; then
    echo "echo said hi'
fi

if [[ $(true) ]]; then #true is a program that just quits with successful exit status
    echo "This shouldn't execute"
fi

你的第三个例子与你的第一个例子相同,非常多。如果要对变量进行分组,可以使用花括号。例如,如果你想在某事之后加上's'。

WORD=Bike
echo "$WORDS" #won't work because "WORDS" isn't a variable
echo "${WORD}S" # will output "BikeS"

然后在第五个示例中,您正在运行位于command内的程序。

因此,如果要测试某些字符串,请使用[[]]或[]。如果您只想测试程序的退出状态,那么不要使用它们,只需使用裸.if。

检查man test以了解大括号的详细信息。

答案 2 :(得分:1)

如果您只是检查命令的返回值,请删除双括号。

if $command
then
    echo "Command succeeded"
else
    echo "Command failed: $!"
fi

双括号是 test 命令。 (嗯,不是真的,但他们是单个方括号的起飞,它是test命令的别名。)在早期的Bourne shell中,你会看到如下内容:

if test -z "$string"
then
    echo "This is an empty string"
fi

方括号是句法糖:

if [ -z "$string" ]
then
    echo "This is an empty string"
fi

因此,如果您没有进行实际测试,可以取消双方或单方括号。

如果你使用方括号,你应该使用双精度数而不是单数,因为双精度数更宽容,可以多做一点:

if [ -z $string ]    #  No quotes: This will actually fail if string is zero bytes!

if [[ -z $string ]]  #  This will work despite the lack of quotes