You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Bash脚本Heredoc中逐行读取文件时echo无输出的原因

问题根源:Heredoc的变量提前展开

你的echo "$line"没有输出,核心原因是变量展开的时机不对

在默认的heredoc(<<- EOF)里,所有以$开头的变量都会在当前执行sudo su的shell里提前展开,而不是等到切换到$my_user的shell后再处理。但$line是你在heredoc内部的while read循环里才定义的变量,当前shell根本不知道它的存在,所以展开后就是空字符串,自然echo没有任何输出。而echo "Test"没有变量,所以能正常打印4次。

两种解决方案

方案1:转义变量的$符号

echo "$line"改成echo "\$line",让$在当前shell里不被展开,留到目标shell处理:

func_two() {
    sudo su - $my_user -s /bin/bash <<- EOF
        while read -r line || [[ -n "$line" ]]; do
            echo "\$line"
            echo "Test"
        done < "/home/$my_user/file.txt"
EOF
}

方案2:使用单引号包裹heredoc结束标记

<<- EOF改成<<- 'EOF',这样整个heredoc内容都会被当作纯字符串,所有变量展开都会延迟到目标shell中进行,这是更简洁的做法:

func_two() {
    sudo su - $my_user -s /bin/bash <<- 'EOF'
        while read -r line || [[ -n "$line" ]]; do
            echo "$line"
            echo "Test"
        done < "/home/$my_user/file.txt"
EOF
}
验证效果

修改后重新执行bash script_a.sh,你就能看到file.txt里的每一行内容和对应的Test都正常输出了。

内容的提问来源于stack exchange,提问作者Ntwali B.

火山引擎 最新活动