分配' test'的结果变量

时间:2014-07-22 19:43:25

标签: bash

我正在编写一个脚本,我需要在几个地方使用文件测试的输出,包括shell函数内部。我想将文件存在分配给shell变量,如:file_exists=[ -f $myfile ]

为了确保我已经覆盖了我的基地,我首先触摸一个文件,并测试它的存在:

file='a'
touch $file
if [ -f $file ]
then
    echo "1 -- '$file' exists"
fi

输出:

1 -- 'a' exists

该文件已成功创建 - 没有任何意外,但至少我知道我没有处理任何权限问题或任何事情。

接下来我测试以确保我可以在变量中存储布尔表达式:

mytest=/bin/true

if $mytest
then
    echo "2 -- \$mytest is true"
fi

输出:

2 -- $mytest is true

所以我已经涵盖了基础知识 - 条件表达式应该发出与/bin/true/bin/false相同的输出......但这不是我所看到的:

mytest=[ -f $file ]
if $mytest
then
    echo "3 -- \$mytest is true [expect true]"
else
    echo "3 -- \$mytest is false [expect true]"
fi

此操作失败,并显示以下错误:

-f: command not found

如果我使用test -f $file而不是[ -f $file ],我会收到相同的错误消息。

如果我在[前放置一个空格,则错误就会消失......

mytest= [ -f $file ]
if $mytest
then
    echo "4 -- \$mytest is true [expect true]"
else
    echo "4 -- \$mytest is false [expect true]"
fi

输出似乎是正确的:

4 -- $mytest is true [expect true]

...但是如果删除文件,我应该得到相反的结果:

rm $file
mytest= [ -f $file ]
if $mytest
then
    echo "5 -- \$mytest is true [expect false]"
else
    echo "5 -- \$mytest is false [expect false]"
fi

......我没有:

5 -- $mytest is true [expect false]

公平地说,我预计这个空间会弄乱真相值:

mytest= /bin/false
if $mytest
then
    echo "6 -- \$mytest is true [expect false]"
else
    echo "6 -- \$mytest is false [expect false]"
fi

输出:

6 -- $mytest is true [expect false]

那么,如何将test内置的输出存储在shell变量中?

5 个答案:

答案 0 :(得分:28)

正如其他人在此记录的那样,使用字符串" true"是一只红鲱鱼;这是 not 在shell脚本中存储布尔值的合适方法,因为评估它意味着动态调用命令而不是简单地使用脚本中硬编码的shell内置函数来检查存储的值。

相反,如果您确实必须存储退出状态,请将其作为数值:

[ -f "$file" ]               # run the test
result=$?                    # store the result

if (( result == 0 )); then   # 0 is success
  echo "success"
else                         # nonzero is failure
  echo "failure"
fi

答案 1 :(得分:7)

你需要引用空格:

mytest='[ -f $file ]'
if $mytest; then echo yes; fi

然而,这非常脆弱且可能不安全。有关详细讨论和更好的方法,请参阅http://mywiki.wooledge.org/BashFAQ/050

如果要封装一段复杂的代码,通常可以使用函数:

mytest () { [ -f "$file" ]; }
if mytest; then echo yes; fi

如果您想运行一次代码并存储其结果以便稍后检查,我会将其改为:

if [ -f "$file" ]; then
    mytest=true
else
    mytest=false
fi
if $mytest; then echo yes; fi

答案 2 :(得分:3)

mytest=/bin/true字符串 /bin/true存储在$mytest变量中。

mytest=[ -f $file ]在命令$mytest的持续时间内将[变量设置为值-f $file ](由于没有{{1},因此输出指示失败命令可用)。

-f(如上所述)在mytest= [ -f $file ]命令的持续时间内将$mytest变量的值设置为空白(并返回[ -f $file ]返回的任何内容)。< / p>

[这与上面的情况相同,只有正在运行的命令是mytest= /bin/false

如果要将命令中的返回代码存储在变量中,可以执行

/bin/false

如果要将命令的输出存储在可以执行的变量中

/bin/true
ret=$?

(虽然使用out=$(/bin/true) 该变量将为空,因为它不输出任何文本。

对于您的情况,您需要以前的/bin/true模型。

此外,在脚本中使用$?(和/或set -x)可能有助于您诊断。

答案 3 :(得分:1)

一个旧的但留在这里供可能需要的人参考。不是最漂亮的解决方案,但可以在bash中使用:

mytest=$( [ -f $file ] ; echo $? )

在子进程(<!>系统负载)中,先评估条件,然后将结果回显到变量$ mytest捕获的输出中。

答案 4 :(得分:0)

带有测试命令的不同版本。

fileExists=$(test -f /path/to/file && echo true || echo false)
if [[ ${fileExists} == "true" ]]; then
    # Your code here
fi

或更简单的版本。

fileExists=$(test -f /path/to/file && echo 1)
if [[ -z ${fileExists} ]]; then
    # Your code here
fi