2012-11-07 35 views
3

我带星号的是bash shell中执行一个MySQL声明:如何将星号传入bash heredoc?

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

echo $query 

echo $query | mysql database 

问题是星号是由文件列表在当前目录更换和查询变得错误。如何避免这种行为?无论我使用反引号还是$()都没关系。我希望有一些转义序列,如\*,但至少这一个不起作用。

+0

为什么'\ *'不起作用?你面临的问题是什么? –

+0

@KingsIndian这样,它就像“SELECT \ * FROM table”一样打印出来。 – Kalmar

+0

您需要'set -f' - 请参阅下面的答案。 –

回答

4

您可以防止参数扩展,命令替换,和这里的文档在算术扩展可以援引分隔字符串:

... <<\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支持这里串,最近的版本庆典支持他们的):

mysql <<< "$query" 
1

为了防止*等水珠charcters从扩大。禁用通配符次使用set -f这里文档

摆脱任何这里文档的分隔符的字符是否意味着没有parameter expansioncommand substitutionarithmetic expansion,或pathname expansion进行前 - 然而,pathname expansion有一个告诫

man bash

  • 路径名扩展 - 字分开后,*除非-f选项设置,bash的扫描每个字的字符*,和[?如果出现这些字符中的一个,则将该字视为模式,并用符合该模式的按字母顺序排列的文件名列表替换。

  • shell内建Commnds - 设置-f - 禁用路径扩展。

help set

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