在这里读取文件bash脚本

时间:2014-11-12 17:58:08

标签: bash heredoc

当我执行此操作时,我只得到空行作为输出

# /bin/bash <<- EOF
while read a
do
    echo $a
done < /etc/fstab
EOF

如果我将here-document的内容复制到文件中并执行它,一切都按预期工作(我得到/ etc / fstab文件的内容)。

有人可以解释原因吗?

更新: 回答一个问题,为什么我需要通过这里来传递这样的文件,这就是我实际上想要做的事情:

ssh user@host /bin/bash <<- EOF
       while read f; do
               sed -i -e "s/$OLD_VAL/$NEW_VAL/g" $f
       done < /tmp/list_of_files
EOF

Sed抱怨$ f未设置

3 个答案:

答案 0 :(得分:2)

如果有人碰到这个,这是一个有效的版本:

# /bin/bash <<- EOF
while read a
do
    echo \$a
done < /etc/fstab
EOF

变量a未在父bash脚本中定义。在将here-document传递给子bash之前,它将被替换为空值。为避免替换,应使用“\”转义$ -sign。

答案 1 :(得分:1)

这里你不需要这里的文件。如果你正在尝试一个脚本,你可以这样做:

#!/bin/bash
while read a
do
    echo "$a"
done < /etc/fstab

答案 2 :(得分:0)

我在这里没有足够的声誉来添加评论,所以我不得不回答。

首先,你有多个级别的shell正在进行中。在您的初始示例中,您的HERE文档的语法不正确,但您编辑的更新是正确的。 &lt;&lt; - 将从每行文本中删除一个前导制表符(但不是空格),直到您的EOF分隔符(可能已被命名为任何内容)。使用&lt;&lt;没有&#39; - &#39;希望HEREdoc的每一行都从第0列开始。

接下来,您正在使用ssh从远程主机获取shell。这也意味着您的/ tmp / list_of_files也将存在于远程计算机上。这也意味着应该转义任何本地shell元字符,以确保它被传递到您实际想要扩展的程序/位置。

我不相信HEREdoc是必要的,当你可以将完整的分号分隔的单行传递给ssh时。这也可以让你灵活地让你的本地shell在变量传递给ssh或你的远程shell之前做一些扩展。

OLD=' '
NEW=$'\t'
ssh -q user@host "for filename in \$(</tmp/list_of_files); do gsed -i.\$(date %s) -e 's/'$OLD'/'$NEW'/g' \$filename; done"

让我们不要忘记-i是就地编辑,而不是忽略正则表达式匹配的大/小写的标志。我喜欢在编辑/更改文件的任何时候创建我的文件的备份,所以如果/什么时候有什么破坏,我会有历史记录。