bash eval as if 语句条件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32259648/
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 13:30:35  来源:igfitidea点击:

eval as if statement condition

linuxbashif-statementeval

提问by AlphaBeta

Why is the output of the following statement true?

为什么以下语句的输出为真?

VAR="[[ "x"=="y" ]]"
if eval $VAR ; then
    echo "true"
else
    echo "false"
fi

Is there any other way to use a variable as condition for an if statement in bash?

有没有其他方法可以使用变量作为 bash 中 if 语句的条件?

采纳答案by anubhava

Your quoting is an issue and you need spaces around ==:

您的引用是一个问题,您需要在周围留出空格==

VAR='[[ "x" == "y" ]]'
if eval $VAR ; then
    echo "true"
else
    echo "false"
fi

However you must avoid using evalas far as possible. You can use a function here:

但是,您必须eval尽可能避免使用。您可以在此处使用函数:

fvar() { [[ "x" == "y" ]]; }

Then call it as:

然后将其称为:

if fvar; then
    echo "true"
else
   echo "false"
fi


Reasonswhy your evalcondition is evaluating to truebecause you have VAR="[[ "x"=="y" ]]"where the text inside [[and ]]is being treated as a single string. Which is same as evaluating [[ a ]]or [[ foo ]]

原因为什么你的eval病情正在评估到true,因为你VAR="[[ "x"=="y" ]]"里面的文字,其中[[]]被视为一个字符串。这与评估[[ a ]][[ foo ]]

回答by Scott Plante

My first answer attempt was voted down, so I'll try to clarify in hopes it at least makes it back to 0 and add something of value considering the other answer. I'll admit I was a bit unclear what you were asking.

我的第一次回答尝试被否决了,所以我会尝试澄清,希望它至少让它回到 0 并考虑其他答案添加一些有价值的东西。我承认我有点不清楚你在问什么。

First, are your x and y supposed to be literals or variables? Part of the reason I'm uncertain is the extra quoting in the assignment. Note these are equivalent:

首先,你的 x 和 y 应该是文字还是变量?我不确定的部分原因是作业中的额外引用。请注意,这些是等效的:

$ VAR="[[ "x"=="y" ]]"
$ echo $VAR
[[ x==y ]]
$ VAR="[[ x==y ]]"
$ echo $VAR
[[ x==y ]]

So in this case, saying

所以在这种情况下,说

if eval $VAR ; then

is the same as saying

和说一样

if [[ x==y ]]

When you're having trouble with eval, you'll want to print out the value of your variable like this to see what's being executed.

当您在使用 eval 时遇到问题时,您需要像这样打印出变量的值以查看正在执行的内容。

The x==y is one argument, and the [[ operator on a single string argument says, "is this a non-zero length string?" For example:

x==y 是一个参数,单个字符串参数上的 [[ 运算符表示,“这是一个非零长度的字符串吗?” 例如:

$ if [[ dkfjek ]]; then echo true; else echo false; fi
true
$ if [[ any_non_zero_length_string ]]; then echo true; else echo false; fi
true
$ if [[ "" ]]; then echo true; else echo false; fi
false

To use the == you need whitespace. For example, without and with eval:

要使用 == 您需要空格。例如,没有和有 eval:

$ if [[ x == x ]]; then echo true; else echo false; fi
true
$ if [[ x == y ]]; then echo true; else echo false; fi
false
$ VAR="[[ x == x ]]"; if eval $VAR; then echo true; else echo false; fi
true
$ VAR="[[ x == y ]]"; if eval $VAR; then echo true; else echo false; fi
false

Usually though you really want to avoid eval unless you've really nailed down what the value of the variable can be. Consider a code snippet where you let the user decide the condition to test: you might write something like this in a script:

通常虽然你真的想避免 eval ,除非你真的确定了变量的值可以是什么。考虑一个让用户决定要测试的条件的代码片段:您可以在脚本中编写如下内容:

read -p "type condition> " COND; 
VAR="[[ $COND ]]"; 
if eval $VAR; 
then 
  echo true; 
else 
  echo false;
fi

You might run it expecting input/output like:

您可能会在期望输入/输出的情况下运行它,例如:

type condition> x == x
true

But what if someone entered this?

但是如果有人输入了这个怎么办?

type condition> x == x ]]; touch /tmp/oh-no; [[ true
true

What was $VAR? What about /tmp/oh-no?

什么是 $VAR?/tmp/oh-no 怎么样?

$ echo $VAR
[[ x == x ]]; touch /tmp/oh-no; [[ true ]]
$ ls -l /tmp/oh-no 
-rw-r--r-- 1 splante isiusers 0 Nov  3 15:17 /tmp/oh-no

Remember the syntax is "if <command>". The "[[" is just one possible command, but any compound command can be executed following if. Now suppose instead of touch /tmp/oh-nothe use entered some other more destructive command? It would have executed too.

记住语法是“if <command>”。"[[" 只是一个可能的命令,但任何复合命令都可以在 if 之后执行。现在假设不是touch /tmp/oh-no使用输入了一些其他更具破坏性的命令?它也会被执行。

You asked "Is there any other way to use a variable as condition for an if statement in bash?" This is the typical way to compare two variables for string equivalence in bash:

您问“有没有其他方法可以将变量用作 bash 中 if 语句的条件?” 这是在 bash 中比较字符串等价的两个变量的典型方法:

if [[ "$x" = "$y" ]]; then ...

I assume now you already knew this, but I almost never use eval and just try to work the problem out differently so you don't need to have the whole condition be a variable.

我假设现在您已经知道这一点,但我几乎从不使用 eval,只是尝试以不同的方式解决问题,因此您不需要将整个条件设为变量。