我的 bash while 循环之间有什么区别?

我的 bash while 循环之间有什么区别?

文件:

cat csvfile
apple,1
orange,2
banana,3

代码:

head -2 csvfile | while read line
do
        f1=$(echo $line | cut -d ',' -f1)
        f2=$(echo $line | cut -d ',' -f2)
        echo "$f1 -> $f2"
done

while read line
do
        f1=$(echo $line | cut -d ',' -f1)
        f2=$(echo $line | cut -d ',' -f2)
        echo "$f1 -> $f2"
done <<< $(head -2 csvfile)

输出:

apple -> 1
orange -> 2
apple -> 1 orange

答案1

问题是这样的:

$ echo "$(head -2 csvfile)"
apple,1
orange,2

$ echo $(head -2 csvfile)
apple,1 orange,2

当不加引号时,命令替换结果将受到单词拆分将所有空格序列(包括换行符)转换为单个空格。

现在只有一行需要迭代,echo $line | cut -d, -f2输出1 orange

忘记在 bash/POSIX shell 中引用变量的安全隐患


另一个潜在的问题将会出现循环结束:考虑

head -2 csvfile | while read line
do
        f1=$(echo $line | cut -d ',' -f1)
        f2=$(echo $line | cut -d ',' -f2)
        echo "$f1 -> $f2"
done
echo "$f1 -> $f2"

将输出->

while read line
do
        f1=$(echo $line | cut -d ',' -f1)
        f2=$(echo $line | cut -d ',' -f2)
        echo "$f1 -> $f2"
done < <(head -2 csvfile)    # <<< a Process Substitution
echo "$f1 -> $f2"

orange -> 2将按预期输出。

Bash 管道在单独的子 shell 中执行每个命令。如果while read管道中最后一个命令,则其变量将在该子 shell 退出时消失。

如果你需要变量持久化,就不要管道输入到 while 循环中,重定向输入。

进一步阅读:

相关内容