【问题标题】:How to pass an asterisk into bash heredoc?如何将星号传递给 bash heredoc?
【发布时间】:2012-10-27 09:48:20
【问题描述】:

我在 bash shell 中执行带有星号的 MySQL 语句:

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

echo $query

echo $query | mysql database

问题是星号被当前目录中的文件列表替换,查询就出错了。如何避免这种行为?我使用反引号还是$() 都没有关系。我希望有一些像\* 这样的转义序列,但至少这个不起作用。

【问题讨论】:

  • 为什么\* 不起作用?你面临的问题是什么?
  • @KingsIndian 这样它就可以像SELECT \* FROM table一样简单地打印出来。
  • 您需要set -f - 请参阅下面的答案。

标签: mysql bash glob heredoc


【解决方案1】:

您可以通过引用分隔符字符串来防止此处文档中的参数扩展、命令替换和算术扩展:

... <<\EndOfMySQL
...
EndOfMySQL

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

编辑: 请注意,here-doc 的行不受文件名生成(通配符)的影响!

我想在这种情况下的问题是你没有引用变量 传递给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"

【讨论】:

    【解决方案2】:

    防止* 和其他全局字符扩展。禁用 globbing – 在你的 Here Document 之前使用 set -f

    转义Here Document的分隔符的任何字符确实意味着不执行parameter expansioncommand substitutionarithmetic expansionpathname expansion – 但是,pathname expansion 有一个警告

    来自man bash

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

    • Shell 内置命令 — set -f - 禁用路径名扩展。

    来自help set

    • -f – 禁用文件名生成(通配符)。

    【讨论】:

      【解决方案3】:

      如何将星号传递给 bash heredoc?

      这样做没有诀窍——here document 可以与星号配合使用。

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

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

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


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

      SELECT $(echo *) FROM table
      

      您可以在 heredoc 的名称周围加上引号以完全禁用扩展:

      cat <<'EndOfMySQL'
      

      另见:How can I write a heredoc to a file in Bash script?

      【讨论】:

      猜你喜欢
      • 2018-05-06
      • 1970-01-01
      • 1970-01-01
      • 2020-11-02
      • 1970-01-01
      • 2019-05-30
      • 1970-01-01
      • 2015-12-31
      • 2018-05-22
      相关资源
      最近更新 更多