我的文件中有以下代码块:
175 MY_IP=`ifconfig eno1 | grep netmask | tr -s ' ' | cut -d " " -f 3`
176 echo "" > /home/hadoop/.ssh/config
177 cat > /home/hadoop/.ssh/config <<EOF
178 Host `echo $MY_IP | sed 's/.[0-9][0-9]*$//g'`.* 0.0.0.0 master worker*
179 StrictHostKeyChecking no
180 UserKnownHostsFile=/dev/null
181 EOF
我希望将第 178 行到第 181 行写入文件,但我得到以下错误输出:
/script.sh: line 178: unexpected EOF while looking for matching `''
/script.sh: line 184: syntax error: unexpected end of file
为什么它不只是复制该文本而不检查其语法?
更新:我的代码和错误消息现在的样子:
175 MY_IP=`ifconfig eno1 | grep netmask | tr -s ' ' | cut -d " " -f 3`
176 echo "" > /home/hadoop/.ssh/config
177 cat > /home/hadoop/.ssh/config <<EOF
178 Host `echo $MY_IP | sed "s/.[0-9][0-9]*$//g"`.* 0.0.0.0 master worker*
179 StrictHostKeyChecking no
180 UserKnownHostsFile=/dev/null
181 EOF
182
183 chown -R hadoop:hadoop /home/hadoop
/script.sh:第 175 行:查找匹配的“”时出现意外的 EOF
/script.sh:第 184 行:语法错误:意外的文件结尾
已解决:检查我的代码后,我发现第一行中缺少单引号。将其与另一个配对解决了该问题。
答案1
shell 将`echo ...`
在此处的文档中执行不同类型的扩展(包括像您的命令替换,还有变量和算术扩展)除非分隔符被引用。
比较:
cat <<EOF
$$ $((2 + 3)) $(hostname) `date`
EOF
4502 5 fazq Mon Mar 11 23:03:27 EET 2019
对比:
cat <<'EOF'
$$ $((2 + 3)) $(hostname) `date`
EOF
$$ $((2 + 3)) $(hostname) `date`
在最后一种情况下,双引号或单引号都可以。
答案2
从man bash
:
这里的文件
这种类型的重定向指示 shell 从当前源读取输入,直到仅包含分隔符的行(没有尾随空格)被看到。到该点读取的所有行都将用作命令的标准输入(或文件描述符 n,如果指定了 n)。
正如问题中当前发布的那样,您的 EOF 行包含尾随空格。删除它们。
答案3
我们这里没有完整的脚本,但请注意,当您将此处文档中的引号从单引号更改为双引号时,“查找匹配 [单引号] 时出现意外的 EOF” 上的行号如何从 178 更改为 175引号。
这向我暗示,实际的问题(未完成的引用)位于您发布的片段之前的某个位置。
例如,在下面的脚本中实际的错误显然在第一行,但从 shell 的角度来看,从那里开始的带引号的字符串一直持续到下一个引号,依此类推,未配对的字符串是后面的字符串bar
(注意语法突出显示如何明显表明第二个echo
被引用,foo
并且bar
没有被引用):
$ cat quote.sh
echo 'error here
echo 'foo' 'bar'
$ bash quote.sh
quote.sh: line 3: unexpected EOF while looking for matching `''
quote.sh: line 4: syntax error: unexpected end of file
将第二个echo
命令更改为echo "foo" "bar"
将在第 1 行显示错误,因为这将是最终单引号字符串开始的行。
您需要更仔细地查看整个脚本。或者将其转储到 shellcheck.net,它会注意到类似的情况。