我想了解 bash 执行行解释的确切过程。
来自 GNU bash 参考手册:
When a simple command is executed, the shell performs the following expansions, assignments, and redirections, from left to right.
1. The words that the parser has marked as variable assignments (those preceding the command name) and redirections are saved for later processing.
2. The words that are not variable assignments or redirections are expanded (see Shell Expansions). If any words remain after expansion, the first word is taken to be the name of the command and the remaining words are the arguments.
3. Redirections are performed as described above (see Redirections).
4. The text after the ‘=’ in each variable assignment undergoes tilde expansion, parameter expansion, command substitution, arithmetic expansion, and quote removal before being assigned to the variable.
If no command name results, the variable assignments affect the current shell environment. Otherwise, the variables are added to the environment of the executed command and do not affect the current shell environment. If any of the assignments attempts to assign a value to a readonly variable, an error occurs, and the command exits with a non-zero status.
If no command name results, redirections are performed, but do not affect the current shell environment. A redirection error causes the command to exit with a non-zero status.
If there is a command name left after expansion, execution proceeds as described below. Otherwise, the command exits. If one of the expansions contained a command substitution, the exit status of the command is the exit status of the last command substitution performed. If there were no command substitutions, the command exits with a status of zero.
现在让我们举一个简单的例子:
var="hello friend"
echo ${var}s > log.txt
现在会发生什么?
根据参考, var 赋值 (1) 将在扩展 (4) 之后进行,但是 shell 如何在不首先执行变量赋值的情况下扩展 var 呢?
我不知道这是我在这里错过的东西还是只是对手册的误解。
如果您能为我提供更多示例以供进一步理解,我将不胜感激。
谢谢
答案1
...扩展、分配和重定向,从左到右。
手册上确实有不是提到它也解析自从上到下,一行接着一行。它只谈论简单的命令。
你随时可以改变
cmd1
cmd2
进入
cmd1; cmd2
但正常情况下
com ma nd 1
co mma nd 2
被人类优先选择
com ma nd 1; co mma nd 2
在 bash 中你没有=
vs. ==
,所以它需要这种特殊的语法作业。重定向也提到了,这些你可以放在任何地方:
> log.txt echo ${var}s
echo ${var}s>log.txt
线路延续反之亦然:
com \
mand 1
答案2
您有 2 个简单的语句,每行 1 个。所以对于第一行步骤1,2和3什么都不做,然后步骤4是变量赋值。
对于第二行,变量在步骤 1 中展开。
答案3
这不是同一条线。 shell 将执行这些步骤两次。
另外请注意这些:
var="hello friend"; echo ${var}s > log.txt
也是两个简单的命令。但是这个:
varr="hello friend" echo ${varr}s > log.txt
是一个简单的命令。在这种情况下,您的疑问适用:${varr}
将扩展为一个空字符串(除非它是之前分配的;我故意使用了一个新名称,所以旧的分配不会干扰)。