我一直在尝试将以下代码转换为使用'test'而不是'if'
if [ -e ./blah ] && [ ! -L ./blah ];
then
exit 1
fi
我的意图是使用测试代替,这样我就不必明确地退出1。我正在尝试这样的事情:
test -e ./blah && ! -L ./blah;
而不是&&,我尝试了-a,使用不同的支架组合,但我没有成功。我相信应该有一个简单的方法来做到这一点。任何人都可以帮助我吗?
答案 0 :(得分:5)
test
无法理解逻辑运算符&&
和||
。您可以使用test -e ./blah -a ! -L ./blah
,但如果您使用的是bash,则还可以切换到更强大的[[ .. ]]
构造:
[[ -e ./blah && ! -L ./blah ]]
答案 1 :(得分:2)
要使if [ -e ./blah ] && [ ! -L ./blah ];
正常工作,请使用以下内容
if [ -e ./blah -a ! -L ./blah ];
(-a
代表and
)http://tldp.org/LDP/abs/html/comparison-ops.html
但是,正如其他人所指出的,[[ .. ]]
构造比[...]
更强大。
答案 2 :(得分:1)
你可以将它们全部组合起来(包括if if fi):
[[ -e ./blah && ! -L ./blah ]] && exit 1
答案 3 :(得分:1)
使用[[
关键字,因为它更强大。
if [[ -e ./blah && ! -L ./blah ]]
then
...
fi
但是,为了确保可移植性,你也可以做这样的事情
if [ -e ./blah ] && [ ! -L ./blah ]
then
...do something
fi
答案 4 :(得分:1)
当您要求使用test
时,您可以这样做:
test -e ./blah && test -L ./blah || ( echo 'First action' ; echo 'Second action )
不同的运算符(&&
,||
等...)首先由shell解析,因此您无法在命令参数中使用它。
答案 5 :(得分:1)
if [ -e ./blah ] && [ ! -L ./blah ];
相当于
if test -e ./blah && test ! -L ./blah;
因此你可以简单地写
test -e ./blah && test ! -L ./blah
即便:
$ help [\[] | tail -n +3
[: [ arg... ]
Evaluate conditional expression.
This is a synonym for the "test" builtin, but the last argument must
be a literal `]', to match the opening `['.
答案 6 :(得分:1)
执行以下操作:
$ ls -i /bin/test
54008404 /bin/test
$ ls -i /bin/[
54008404 /bin/test
54008404
是 inode 号码。这是文件的真实名称。 /bin/test
只指向inode
,inode
包含所有文件信息。
需要注意的是/bin/[
和/bin/test
是相同的 inode 。这意味着,他们是同一个命令。
因此:
if [ -f "$foo" ]
与:
相同if test -f "$foo"
if
命令执行给定的命令,然后如果命令返回true则执行if
子句,如果命令为false则不执行该子句。
例如:
if grep -q "foo" $foo
then
echo "File $foo contains the regular expression /foo/"
fi
完全有效。 grep -q
命令(在grep
的许多变体中意味着搜索正则表达式,如果该正则表达式在文件中,则返回退出代码0
(这意味着命令成功)并且是真的。)
注意没有方括号。
test
命令(或[...]
)仅按指定运行测试,如果测试为真,则返回退出代码0
(因此命令成功) 。就是这样。
您可能还会看到此构造:
[ "$foo" = "$bar" ] && echo "$foo is equal to $bar"
&&
表示如果第一个命令返回零退出代码,则执行下一个命令(并返回退出代码)。否则,只需返回第一个命令的退出代码。
因此:
if [ -e ./blah ] && [ ! -L ./blah ];
表示运行test -e ./blah
并且如果为真(即文件存在)执行test ! -L ./blah
,如果也是如此,则运行语句的if
子句。 / p>
请注意,[ -e ./blah]
和[ ! -L ./blah ]
是两个单独的命令。 &&
将两个命令组合在一起:
[ "$foo" = "$bar" ] && some_command;
这就是说,运行test "$foo" = "$bar"
如果是,请运行命令some_command
。请注意,这相当于:
if [ "$foo" = "$bar" ]
then
some_command
fi
另一个列表结构是||
。这意味着如果第一个命令成功,则返回退出代码0
,并且不运行第二个命令。因此:
[ "$foo" = "$bar" ] || some_command;
与:
相同if [ "$foo" = "$bar" ]
then
:
else
some_command
fi
让我们回到你原来的问题:
if [ -e ./blah ] && [ ! -L ./blah ];
then
exit 1
fi
与:
相同if test -e ./blah && test ! -L ./blah
then
exit 1
fi
与
相同test -e ./blah && test ! -L ./blah && exit 1
这意味着:如果test -e ./blah
为真(./blah是文件),则在&&
列表运算符后执行命令。这是test -! -L ./blah
。如果此测试也为真,请再次在&&
列表运算符后运行命令。
这也可以改写为:
test -e ./blah && test -L ./blah || exit 1
这表示如果test -e ./blah
为真,请在&&
列表运算符后运行命令。如果test -L ./blah
为false,请在||
运算符后运行命令。