首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 ><<EOF与<‘EOF’之间的差异

<<EOF与<‘EOF’之间的差异
EN

Stack Overflow用户
提问于 2020-05-07 01:41:47
回答 3查看 2.2K关注 0票数 3

GNU 3.6.6这里的文件

n<<-word此处-文档分隔符 如果word的任何部分是引号,则分隔符是删除word引号的结果,此处文档中的行不会展开。如果word未引用,则此处文档的所有行都会受到参数展开、命令替换和算术扩展,字符序列\newline将被忽略,“\”必须用于引用字符“\”、“$”和“`”。

如果我用EOF单引号,就行了。我认为,因为bash /bin/bash要调用的进程得到未展开的字符串,然后被调用的进程解释行。

代码语言:javascript
复制
$ /bin/bash<<'EOF'
#!/bin/bash
echo $BASH_VERSION
EOF               
3.2.57(1)-release

但是,下面的内容会导致一个错误。我认为BASH_VERSION已经被扩展,当前bash进程的版本被传递给要调用的/bin/bash进程。但不起作用。

代码语言:javascript
复制
$ /bin/bash<<EOF 
#!/bin/bash
echo $BASH_VERSION
EOF               
/bin/bash: line 2: syntax error near unexpected token `('
/bin/bash: line 2: `echo 5.0.17(1)-release'
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-05-07 01:52:13

/bin/bash<

正如您可以从错误消息中推断出来的那样,本文档将被扩展为:

代码语言:javascript
复制
/bin/bash<<EOF 
#!/bin/bash
echo 5.0.17(1)-release
EOF

听起来就像你所期望的:它正在被扩展到外壳的版本。问题不在于此文档或扩展;问题在于未引用的括号是语法错误。尝试手动运行echo命令,您将得到相同的错误:

代码语言:javascript
复制
$ echo 5.0.17(1)-release
bash: syntax error near unexpected token `('

要解决这个问题,您可以添加额外的引号:

代码语言:javascript
复制
/bin/bash<<EOF 
echo '$BASH_VERSION'
EOF

这将工作和打印外壳的版本。我使用单引号来证明这些引号不会抑制变量的扩展。外壳没有看到这些引号。只有内壳才能做到。

(我也摆脱了#!/bin/bash的“谢邦线”。没有必要这样做,因为您正在显式调用bash。)

然而,的报价并不是100%的健壮。,如果$BASH_VERSION碰巧包含单引号,那么您就有问题了。引号使括号( )安全,但它们不是万无一失的。作为一个一般的技术,如果你想让这是完全安全的,无论什么特殊的角色在游戏中,你将不得不跳过一些丑陋的箍。

  1. 使用printf '%q'转义所有特殊字符。 /bin/bash <这将扩展到echo 5.0.17\(1\)-release
  2. 将其作为环境变量传入,并使用<<'EOF'禁用脚本中的内插。 OUTER_VERSION="$BASH_VERSION“/bin/bash <<' EOF‘回声"$OUTER_VERSION”EOF 这将是我的选择。我更喜欢尽可能地使用<<'EOF'表单。让父shell内插要传递给子shell的脚本可能会让人感到困惑和难以解释。此外,显式的$OUTER_VERSION变量使它非常清楚正在发生什么。
  3. 使用bash -c 'script'而不是heredoc,然后将版本作为命令行参数传递进来。 bash -c‘回声“$1’bash‘$BASH_VERSION’ 我可能会用这个作为单行脚本。
票数 5
EN

Stack Overflow用户

发布于 2020-05-07 01:51:17

如果不引用EOF,则在将原始shell作为输入传递给被调用的shell之前,将原始shell中的变量展开。所以这相当于执行

代码语言:javascript
复制
echo 3.2.57(1)-release

在调用的shell中。这是无效的bash语法,因此您将得到一个错误。

引用这个词可以阻止变量展开,因此调用的shell接收$BASH_VERSION,并扩展它本身。

票数 2
EN

Stack Overflow用户

发布于 2020-05-07 01:53:06

在第一种情况下,引号阻止了这里文档中的任何更改,因此子shell可以看到echo $BASH_VERSION,并展开字符串并回显它。

在第二种情况下,缺少引号意味着第一个shell扩展信息并看到echo 3.2.57(1)-release,如果在命令行输入该引用,则会得到语法错误。

如果在这两种情况下都使用echo "$BASH_VERSION",那么两者都可以工作,但是不同的shell会扩展$BASH_VERSION

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61648422

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档