我习惯于使用这样的行来测试变量是否具有非空值(或给出消息和保释):
test $variable || (echo "Value of \$variable cannot be null."; exit 1)
我在我的脚本中使用函数是一个新手,但我有一个案例,我需要确保传递非空值或保留该函数。但是,“或”案例的命令分组在函数内部的工作方式不同。我写了这个小小的测试脚本来演示:
$ cat -n bubu.sh
1 #!/bin/bash
2
3 read -p "give a value for variable \$foo: " -e -i "bar" foo
4
5 function firstfunc {
6 test $1 || (echo "no value"; return 1)
7 echo it looks like \"$1\" is the first value of \$foo
8 return 0
9 }
10
11 function secondfunc {
12 test $1 || return 1
13 echo it looks like \"$1\" is the second value of \$foo
14 return 0
15 }
16 echo "first function:"
17 firstfunc $foo
18 echo returned $?
19
20 echo "second function:"
21 secondfunc $foo
22 echo returned $?
变量具有值的情况下的输出如下:
$ ./bubu.sh
give a value for variable $foo: bar
first function:
it looks like "bar" is the first value of $foo
returned 0
second function:
it looks like "bar" is the second value of $foo
returned 0
不值
的情况下的输出$ ./bubu.sh
give a value for variable $foo:
first function:
no value
it looks like "" is the first value of $foo
returned 0
second function:
returned 1
在没有值的第一个函数中,我得到“或”命令组的第一个命令,并且“无值”回显,但返回命令被传递,其余的函数被执行,向下回归。
为什么命令分组的parens在函数内部表现不同,或者我还缺少什么?
答案 0 :(得分:3)
正如其他人所提到的,parens创建了一个子shell,exit或return命令指示bash退出子shell。你应该使用花括号。请注意,您可以使用bash参数替换以更简单的方式获得相同的效果。见下文。
您的第test $variable || (echo "Value of \$variable cannot be null."; exit 1)
行甚至不应该在函数上下文的“外部”工作。例如:
$ cat t.sh
#!/bin/bash
a="hello"
test $a || (echo "Value of \$variable cannot be null."; exit 1)
echo First test passed
a=
test $a || (echo "Value of \$variable cannot be null."; exit 1)
echo Second test passed
给出:
$ ./t.sh
First test passed
Value of $variable cannot be null.
Second test passed
$
我们看到第二个echo
即使它没有运行。使用花括号是要走的路。
$ cat t.sh
#!/bin/bash
a="hello"
test $a || { echo "Value of \$variable cannot be null."; exit 1 ; }
echo First test passed
a=
test $a || { echo "Value of \$variable cannot be null."; exit 1 ; }
echo Second test passed
$ ./t.sh
First test passed
Value of $variable cannot be null.
$
请注意,您可以使用bash ${parameter:?err_msg}
构造进行参数替换:
$ cat t.sh
#!/bin/bash
a="hello"
: ${a:?'a is null or undefined! Exiting..'}
echo First test passed
a=
: ${a:?'a is null or undefined! Exiting..'}
echo Second test passed
$ ./t.sh
First test passed
./t.sh: line 9: a: a is null or undefined! Exiting..
$
答案 1 :(得分:1)
()
周围的echo "no value"; return 1
将在子shell中运行这些命令。 return
只会让你退出子shell,而不是退出函数。您可以使用{}
来实现没有子shell的命令分组。在结束return
之前,请确保;
后跟}
:
6 test $1 || { echo "no value"; return 1; }
有关详细信息,请参阅Bash manual command grouping section。
答案 2 :(得分:1)
在括号内,return
和exit
导致括号创建的子shell退出,而不是执行... || ...
列表的shell。您想要使用{...}
。
function firstfunc {
test $1 || { echo "no value"; return 1; }
echo it looks like \"$1\" is the first value of \$foo
return 0
}
请注意,大括号比括号更挑剔:最后一个命令后面必须跟一个分号,你必须确保大括号用空格与周围的字符隔开。