我是 bash 脚本的新手,有两个循环如下:
#!/bin/bash
##########
# Loop 1 #
##########
for x in "one two three four";
do
echo $x
done
Run Code Online (Sandbox Code Playgroud)
输出:
one two three four
Run Code Online (Sandbox Code Playgroud)
##########
# Loop 2 #
##########
var="one two three four"
for x in $var;
do
echo $x
done
Run Code Online (Sandbox Code Playgroud)
输出:
one
two
three
four
Run Code Online (Sandbox Code Playgroud)
我正在寻找指针来帮助理解为什么第一个循环echo是字符串,而第二个循环在空格处拆分,然后echo是每个拆分的单词。
编辑:为了清楚起见,重新表述了问题。
这里的基本误解如下:shell不遍历字符串;它只循环遍历它所谓的“单词”列表。当您执行不带引号的扩展(如$var)时,除非它在隐式抑制字符串拆分(也称为“分词”)的上下文中,否则 的内容$var将在IFS(默认情况下:制表符、空格和换行符)中的字符上拆分以形成一个单词列表,然后每个单词都扩展为一个 glob(因此*.txt可以替换为a.txt b.txt c.txt-- 或者file one.txt,就此而言,如果当前目录中存在包含空格的匹配名称)。
In for x in "one two three four", one two three four-- 因为它被引用了 -- 是一个词。相比之下,for x in one two three fourorfor x in "one" "two" "three" "four"将迭代每个one, two, three, 和four作为一个不同的词。
当你运行var="one two three four"; for x in $var,然后$var是 - 因为扩展没有引用 - 分成多个词,所以one是一个词,two第二个,three第三个,four第四个。
另一方面,如果您运行for x in "$var",引号将抑制字符串拆分和通配符,因此循环内部只会运行一次,整个字符串保持在一起。
最好的做法是根本不使用for x in $var。当您想在 bash 中拥有一个事物列表时,请使用数组来存储该列表。
#!/usr/bin/env bash
# ^^^^ - NOT sh, which doesn't support arrays
var=( "first word" "second word" )
for x in "${var[@]}"; do
echo "$x"
done
Run Code Online (Sandbox Code Playgroud)