1

我一直在尝试将以下代码转换为使用“测试”而不是“如果”

if [ -e ./blah ] &&  [ ! -L ./blah ];
then
   exit 1
fi

我的意图是改用 test ,这样我就不必明确退出 1 。我正在尝试这样的事情:

test -e ./blah  && ! -L ./blah;

而不是&&,我尝试了-a,使用不同的括号组合,但我没有成功。我相信应该有一个简单的方法来做到这一点。谁能帮我 ?

4

7 回答 7

6

test不懂逻辑运算符&&||。您可以使用test -e ./blah -a ! -L ./blah,但如果您使用的是 bash,还可以切换到其更强大的[[ .. ]]构造:

[[ -e ./blah && ! -L ./blah ]] 
于 2013-05-27T15:34:42.897 回答
2

if [ -e ./blah ] && [ ! -L ./blah ];工作,请使用以下 if [ -e ./blah -a ! -L ./blah ];-a代表andhttp://tldp.org/LDP/abs/html/comparison-ops.html

演示——http: //ideone.com/GR8UiK

但是,正如其他人所指出的,[[ .. ]]construct 比[...].

于 2013-05-27T15:46:03.950 回答
1

您可以将它们全部组合起来(包括 if then fi):

[[ -e ./blah && ! -L ./blah ]] && exit 1
于 2013-05-27T15:35:48.793 回答
1

请执行下列操作:

$ ls -i /bin/test
54008404 /bin/test
$ ls -i /bin/[
54008404 /bin/test

54008404inode编号。这是文件的真实名称。/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子句。

请注意,[ -e ./blah]and[ ! -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

让我们回到您的 _original 问题:

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,则在||运算符之后运行命令。

于 2013-05-27T17:22:47.120 回答
1

使用[[关键字,因为它更强大。

if [[ -e ./blah && ! -L ./blah ]]
    then
    ...
fi

但是,为了确保可移植性,您也可以这样做

if [ -e ./blah ] && [ ! -L ./blah  ] 
    then
    ...do something
fi
于 2013-05-27T15:41:51.713 回答
1

当您要求使用test时,您可以这样做:

test -e ./blah && test -L ./blah || ( echo 'First action' ; echo 'Second action )

不同的运算符(&&||,等等...)首先由 shell 解析,因此您不能在命令参数中使用它。

于 2013-05-27T15:44:41.780 回答
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 `['.
于 2013-05-27T15:54:33.150 回答