简体   繁体   English

为什么这个bash代码不起作用?

[英]Why doesn't this bash code work?

x="a=b"
`echo $x`
echo $a

I expect the second line to generate "a=b", and execute it in the context of the main shell, resulting in a new variable a with value b . 我希望第二行生成“a = b”,并在主shell的上下文中执行它,从而产生a值为b的新变量b However, what I really get (if I enter the commands manually) is the error message after the second line, bash: a=b: command not found 但是,我真正得到的(如果我手动输入命令)是第二行之后的错误消息, bash: a=b: command not found

Why is that so? 为什么会这样?

Try 尝试

eval $x

(And we need 30 characters for this answer to be posted) (我们需要30个字符才能发布此答案)

What your first echo line does is running in a subshell and returns its value to the callee.. The same result is achieved using $() and is - by the way - easier to use than backticks. 你的第一个echo行是在子shell中运行并将其值返回给被调用者。使用$()可以获得相同的结果,顺便说一下,比反引号更容易使用。

So, what you are doing is first running echo $x (which returns a=b ). 所以,你正在做的是首先运行echo $x (返回a=b )。 And, because of the backticks, a=b is returned to the shell that tries to run that line as a command which - obviously - won't work. 并且,由于反引号, a=b返回到shell,它试图将该行作为命令运行 - 显然 - 不起作用。

Try this in a shell: 在shell中试试这个:

$(echo ls)

And you will clearly see what is happening. 你会清楚地看到发生了什么。

It's because of the order in which bash parses the command line. 这是因为bash解析命令行的顺序。 It looks for variable definitions (eg a=b ) before performing variable and command substitution (eg commands in backticks). 执行变量和命令替换(例如反引号中的命令) 之前查找变量定义(例如a=b )。 Because of this, by the time echo $x is replaced by a=b , it's too late for bash to see this as a variable definition and it's parsed as a command instead. 因此,当echo $xa=b替换时,bash将其视为变量定义并且将其解析为命令为时已晚。 The same thing would've happened if you'd just used $x as the command (instead of echo in backticks). 如果您只使用$x作为命令(而不是反引号中的echo),那么同样的事情就会发生。 As in @mvds's answer, the eval command can be used to force the command to be reparsed from the beginning, meaning that it'll be recognized as a variable definition: 与@ mvds的答案一样, eval命令可用于强制命令从头开始重新分配,这意味着它将被识别为变量定义:

$ x="a=b"
$ `echo $x`
-bash: a=b: command not found
$ $(echo $x)  # Exact same thing, but with cleaner syntax
-bash: a=b: command not found
$ $x  # This also does the same thing, but without some extra steps
-bash: a=b: command not found
$ eval "$x"  # This will actually work
$ echo $a
b
$ a=  # Start over
$ eval "$(echo "$x")"  # Another way of doing the same thing, with extra steps
$ echo $a
b

Note that when using eval I've put all of the references to $x in double-quotes -- this is to prevent the later phases of bash parsing (eg word splitting) from happening twice , since bash will finish its regular parsing process, then recognize the eval command, and then redo the entire parsing process again . 请注意,当使用eval我将所有对$x的引用都放在双引号中 - 这是为了防止bash解析的后续阶段(例如分词)发生两次 ,因为bash将完成其常规解析过程,然后识别eval命令,然后再次重做整个解析过程。 It's really easy to get unexpected results from using eval , and this removes at least some of the potential for trouble. 使用eval很容易得到意想不到的结果,这至少消除了一些潜在的麻烦。

Did you try $x in that funny apostrophes? 你在那个有趣的撇号中尝试过$x吗? Without echo , echo seems to be only for displaying string, not execute commands. 没有echo ,echo似乎只用于显示字符串,而不是执行命令。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM