Bash if语句:比较不适用于赋值

时间:2020-06-30 14:55:10

标签: bash if-statement

下面的test_if2()可以正常工作,而test_if则不能正常工作。区别在于在test_if()中,我进行了变量分配。错误在哪里?

test_if() {
  declare file_path
  if [[ -n ${file_path=$(echo "")} || -n ${file_path=$(echo "Hi")} ]]; then
    echo Non null: ${file_path}
  else
    echo null
  fi      
}

test_if2() {
  declare file_path
  declare greet="Hello"
  if [[ -n $(echo "") || -n $(echo "Hi") ]]; then
    echo Non null
  else
    echo null
  fi      
}

test_if #prints null
test_if2 #prints Non null

2 个答案:

答案 0 :(得分:1)

针对您要寻找的行为,使用:=代替=

${param=word}如果设置了param但为空(declare param则为空),则不进行分配。也可以使用${param:=word}来覆盖空参数的情况。

您的问题是未执行分配,并且返回的值为空。

我在MacOS上测试了您的表情,如下所示:

file_path=Bye
echo ${file_path=$(echo "Hi")}  # returns Bye 
echo $file_path                 # returns Bye

或者:

unset file_path
echo ${file_path=$(echo "Hi")}  # returns Hi 
echo $file_path                 # returns Hi

最后,让我们看看在考虑unset和empty时是否存在不同的行为:

file_path=""
echo ${file_path=$(echo "Hi")}  # returns nothing 
echo $file_path                 # returns nothing

我们也可以完全重复您的代码:

declare file_path
echo ${file_path=$(echo "Hi")}  # returns Nothing
echo $file_path                 # returns Nothing

因此,如果我们查看您的代码,我们可以看到为什么test_if()返回“ null”。

因此,我将得出结论,只有在未设置param的情况下,$ {param = word}才能进行赋值。请考虑以下代码:

test_if() {
  declare file_path
  if [[ -n ${file_path:=$(echo "")} || -n ${file_path:=$(echo "Hi")} ]]; then
    echo Non null: ${file_path}
  else
    echo null
  fi      
}

echo "test_if() returns $(test_if)" # test_if() returns Non null: Hi

如果参数为空或未设置,则使用:=会分配一个值。因此,这将使您的代码正常工作,因为您声明了file_path,但最初并未分配值,而是将其保留为空(但已设置)。

答案 1 :(得分:1)

file_path="foo"

if [[ -n ${file_path=bar} ]]; then
    echo "got>$file_path<"
else
    echo "no file_path"
fi

如果已经设置file_path,则在参数扩展中分配file_path无效,因此程序将打印

got>foo<

同样的情况也会发生。

第一个条件设置file_path="",并且由于-n测试对于空白字符串失败,因此它将尝试第二个条件。

但是第二个将设置file_path="HI",因为它已经设置为""-第二个-n测试因此也失败了。

相关问题