我正在编写一个脚本,我需要在几个地方使用文件测试的输出,包括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变量中?
答案 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