当我执行此操作时,我只得到空行作为输出
# /bin/bash <<- EOF
while read a
do
echo $a
done < /etc/fstab
EOF
如果我将here文档的内容复制到文件中并执行它,一切都会按预期进行(我得到/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没有设置
如果有人遇到这种情况,这里有一个有效的版本:
# /bin/bash <<- EOF
while read a
do
echo $a
done < /etc/fstab
EOF
变量a未在父bash脚本中定义。在将here文档传递给子bash之前,它将被替换为空值。为了避免替换,$符号应该用"\"转义。
此处不需要文档。如果你正在尝试一个脚本,你可以做:
#!/bin/bash
while read a
do
echo "$a"
done < /etc/fstab
我在这里没有足够的信誉来添加评论,所以我不得不回答。
首先,你有多个级别的shell。在你最初的例子中,HERE文档的语法不正确,但你编辑的更新是正确的。<lt;-将从每行文本中删除一个前导制表符(但不是空格),直到您的EOF分隔符(可以命名为任何名称)。使用<lt;如果没有"-",则HEREdoc的每一行都将从第0列开始。
接下来,您将使用ssh从远程主机获取shell。这也意味着您的/tmp/list_of_files也将存在于远程计算机上。这也意味着任何本地shell元字符都应该进行转义,以确保它被传递到您真正希望它展开的程序/位置。
当您可以将一个完整的分号分隔的一行代码传递给ssh时,我不认为HEREdoc是必要的。这也可以为您提供一些灵活性,让您的本地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是一个就地编辑,而不是一个忽略正则表达式匹配大小写的标志。我喜欢在任何时候编辑/更改我的文件时创建它们的备份,以便在以后发生任何故障时都有一个历史记录。