bash 将“测试”的结果分配给变量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24896433/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 10:55:52  来源:igfitidea点击:

Assigning the result of 'test' to a variable

bash

提问by Barton Chittenden

I'm writing a script where I need to use the output of a file test in several places, including inside a shell function. I would like to assign the file existence to a shell variable, like this: file_exists=[ -f $myfile ].

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

Just to make sure that I've got my bases covered, I start by touching a file, and testing its existance:

只是为了确保我已经涵盖了我的基础,我从触摸一个文件开始,并测试它的存在:

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

Output:

输出:

1 -- 'a' exists

The file was created successfully -- no surprises, but at least I know that I'm not dealing with any permissions issues or anything.

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

Next I test to make sure that I can store a boolean expression in a variable:

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

mytest=/bin/true

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

Output:

输出:

2 -- $mytest is true

So I've got the basics covered -- conditional expressions should emit the same output as /bin/trueor /bin/false... but that's not what I'm seeing:

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

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

This fails with the following error:

这失败并出现以下错误:

-f: command not found

I get the same error message if i use test -f $filerather than [ -f $file ].

如果我使用test -f $file而不是[ -f $file ].

If I put a space in front of the [, the error goes away...

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

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

The output appears to be correct:

输出似乎是正确的:

4 -- $mytest is true [expect true]

... but if I remove the file, I should get the opposite result:

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

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

... and I don't:

......我没有:

5 -- $mytest is true [expect false]

To be fair, I expected the space to mess with the truth value:

公平地说,我预计这个空间会混淆真值:

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

Outputs:

输出:

6 -- $mytest is true [expect false]

So, how do I store the output from the testbuiltin in a shell variable?

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

回答by Charles Duffy

As others have documented here, using the string "true" is a red herring; this is notan appropriate way to store boolean values in shell scripts, as evaluating it means dynamically invoking a command rather than simply inspecting the stored value using shell builtins hardcoded in your script.

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

Instead, if you really must store an exit status, do so as a numeric value:

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

[ -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

回答by tripleee

You need to quote whitespace:

您需要引用空格:

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

However, this is extremely brittle and potentially insecure. See http://mywiki.wooledge.org/BashFAQ/050for a detailed discussion and some better ways to accomplish something similar.

然而,这是非常脆弱的并且可能不安全。请参阅http://mywiki.wooledge.org/BashFAQ/050以获得详细的讨论和一些更好的方法来完成类似的事情。

If you want to encapsulate a complex piece of code, a function is usually the way to go:

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

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

If you want to run the code once and store its result so you can examine it later, I would rephrase it like this:

如果你想运行一次代码并存储它的结果以便你以后检查它,我会像这样改写它:

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

回答by Etan Reisner

mytest=/bin/trueis storing the string/bin/truein the $mytestvariable.

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

mytest=[ -f $file ]is setting the $mytestvariable to the value [for the duration of the command -f $file ](which as your output indicates fails as there is no -fcommand available).

mytest=[ -f $file ]正在将$mytest变量设置[为命令持续时间的值-f $file ](如您的输出所示,由于没有-f可用命令而失败)。

mytest= [ -f $file ](like the above) sets the value of the $mytestvariable to blank for the duration of the [ -f $file ]command (and returns whatever [returns).

mytest= [ -f $file ](像上面一样)$mytest[ -f $file ]命令的持续时间内将变量的值设置为空白(并返回任何[返回值)。

mytest= /bin/falsethis is the same as the above case only the command being run is /bin/false.

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

If you want to store the return code from a command in a variable you can do

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

/bin/true
ret=$?

if you want to store the output from a command in a variable you can do

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

out=$(/bin/true)

(though with /bin/truethat variable will be empty as it outputs no text.

(尽管/bin/true该变量将为空,因为它不输出文本。

For your case you want the former $?model.

对于您的情况,您需要以前的$?模型。

Also, using set -x(and/or set -v) in your scripts might have helped you diagnose this.

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

回答by Jacques

A old one but left this here for reference for people that might need it. Not the most beautiful solution but it works in bash:

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

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

More portable, using the test command, and the backticks:

更便携,使用 test 命令和反引号:

set mytest=`test -f $file ; echo $?`

In a subprocess (<!> system load), the condition is evaluated, and then the result echoed to the output that is captured by the variable $mytest.

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

回答by Václav Ku?el

Different version with test command.

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

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

Or even more simplier version.

或者更简单的版本。

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