4 bash
为什么
for i in {1..5}; do x="${i}" echo "$x"; done
Run Code Online (Sandbox Code Playgroud)
不输出
1
2
3
4
5
Run Code Online (Sandbox Code Playgroud)
?
这样做的正确方法是什么?
(经过测试 for i in {1..5}; do x=$(i) echo "$x"; done
-bash: i: 命令未找到
和别的)
roa*_*ima 10
回答你的问题
为什么不
for i in {1..5}; do x="${i}" echo "$x"; done
输出1
,2
,3
,4
,5
?
原因与在执行期间评估操作的顺序有关。看看这个命令
x="${i}" echo "$x"
Run Code Online (Sandbox Code Playgroud)
这是做什么的
x
所以你得到
x=1 echo ""
(或x=2 echo ""
等)x
设置为值1
echo ""
很可能你的意思是这个命令是两条指令:给 赋值x
,输出它的值。但是在 shell 语法中,您编写的代码是完全合法的代码,因此 shell 毫无异议地执行了它。
您要求回答两个问题:
您要求解释为什么您当前的代码没有产生预期的输出。
您要求以正确的方式编写代码,以便它确实产生预期的输出。
查看您的代码,我可以看到两种可能的解释,说明您为何以这种方式编写代码:
对于 for-loop的语法可能会有一些轻微的混淆。
所谓的simple command 中的求值顺序可能会有些混乱。
在第一种情况下,我会说您在变量赋值后缺少分号。如果你想在一行上写你的 for 循环,那么你需要在循环体中的每个命令后面放一个分号。试试这个:
for i in {1..5}; do x="${i}"; echo "$x"; done
Run Code Online (Sandbox Code Playgroud)
另一种选择是使用多行语法编写 for 循环,用换行符代替分号:
for i in {1..5}
do
x="${i}"
echo "${x}"
done
Run Code Online (Sandbox Code Playgroud)
您还可以混合匹配分号和换行符,例如:
for i in {1..5}; do
x="${i}"; echo "${x}"
done
Run Code Online (Sandbox Code Playgroud)
在第二种情况下,我会说您可能已经假设命令序言中的变量赋值(即x="$i"
赋值)发生在命令主体中的变量扩展(即${x}
in的扩展echo "${x}"
)之前。但事实并非如此。为了验证这一点,我们可以参考在页面上简单的命令扩展在Bash的手册或在简单的命令款在POSIX规范。这两个参考文献都包含以下段落:
“简单命令”是一系列可选的变量赋值和重定向,以任何顺序,可选地跟随单词和重定向,由控制运算符终止。
当需要执行给定的简单命令时(即当任何条件结构如 AND-OR 列表或case语句没有绕过简单命令时),以下扩展、赋值和重定向都应从命令文本的开头到结尾:
根据Shell 语法规则被识别为变量赋值或重定向的单词将被保存以在步骤 3 和 4 中进行处理。
不是变量赋值或重定向的词应该被扩展。如果任何字段在它们的扩展之后仍然存在,则第一个字段应被视为命令名称,其余字段是命令的参数。
应中所描述来执行重定向的重定向。
在分配值之前,每个变量分配都应针对波浪号扩展、参数扩展、命令替换、算术扩展和引号删除进行扩展。
请注意,第 2 步是命令中变量扩展发生的地方,但第 1 步告诉我们变量赋值会一直保存到第 3 步和第 4 步。因此表达式在赋值发生之前echo "${x}"
被扩展到。这解释了为什么你得到空输出。echo ""
x="${i}"
有关此主题的进一步讨论,请参阅以下帖子:
归档时间: |
|
查看次数: |
2032 次 |
最近记录: |