如何将星号传入bash heredoc?

时间:2012-11-07 10:42:59

标签: mysql bash glob heredoc

我在bash shell中用星号执行MySQL语句:

query=`cat <<EndOfMySQL
INSERT tmp_table
SELECT * FROM table
;
EndOfMySQL
`

echo $query

echo $query | mysql database

问题是星号被当前目录中的文件列表替换,并且查询变得错误。如何避免这种行为?我是否使用反引号或$()并不重要。我希望有一些转义序列如\*,但至少这一个不起作用。

3 个答案:

答案 0 :(得分:4)

您可以通过引用分隔符字符串来阻止here-document中的参数扩展,命令替换和算术扩展:

... <<\EndOfMySQL
...
EndOfMySQL

转义单个字符也会阻止上面列出的扩展。

编辑: 请注意,here-doc的行不受文件名生成(globbing)的限制!

我认为在这种情况下的问题是你没有引用变量 传递给 mysql

echo $query | mysql database

应该是:

echo "$query" | mysql database

或更好:

printf '%s\n' "$query" | mysql database

你为什么不用:

query='INSERT into tmp_table
SELECT * FROM table;'
printf '%s\n' "$query" | mysql

或(如果你的shell支持 here-strings ,最新版本的 bash 支持它们):

mysql <<< "$query"

答案 1 :(得分:2)

防止*和其他glob charcters扩展。在此处文档之前禁用 globbing - 使用set -f

转义此处文档的分隔符的任何字符都意味着parameter expansioncommand substitutionarithmetic expansion或{{1已执行 - 但是,pathname expansion有一个 警告

来自pathname expansion

  • 路径名扩展 -    分词后,*除非设置了 man bash 选项,否则bash会扫描每个单词中的字符*,?和[。如果出现其中一个字符,则该单词将被视为模式,并替换为与该模式匹配的按字母顺序排列的文件名列表。

  • Shell Builtin Commnds -    设置 -f - 禁用路径名扩展。

来自-f

  • help set - 禁用文件名生成(通配)。

答案 2 :(得分:0)

如何将星号传递到bash heredoc?

执行此操作没有技巧-here document可以在星号上正常工作。

这个问题是基于对症状的误解(在这里容易犯错误)。

带星号的问题与here-doc或cat的执行无关。 *echo $query期间展开。

您可以通过用cat替换tee temp.txt并检查生成的文件的内容来证明这一点。


但是,其他类型的扩展 被处理(默认情况下),因此,如果您 did 想要扩展星号,则可以执行以下操作:

SELECT $(echo *) FROM table

您可以在Heredoc的名称两边加上引号,以完全禁用扩展功能:

cat <<'EndOfMySQL'

另请参阅:How can I write a heredoc to a file in Bash script?