我在bash shell中用星号执行MySQL语句:
query=`cat <<EndOfMySQL
INSERT tmp_table
SELECT * FROM table
;
EndOfMySQL
`
echo $query
echo $query | mysql database
问题是星号被当前目录中的文件列表替换,并且查询变得错误。如何避免这种行为?我是否使用反引号或$()
并不重要。我希望有一些转义序列如\*
,但至少这一个不起作用。
答案 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 expansion
,command substitution
,arithmetic 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'