我在bash shell中使用星号执行mysql语句:
query=`cat <<EndOfMySQL
INSERT tmp_table
SELECT * FROM table
;
EndOfMySQL
`
echo $query
echo $query | mysql database
问题在于,星号被当前目录中的文件列表替换,并且查询变得错误。如何避免这种行为?无论是使用Backticks还是$()
,都没关系。我希望像 *
这样的逃脱序列,但至少这个序列不起作用。
您可以通过引用定界符字符串来防止参数扩展,命令替换和算术扩展:
... <<EndOfMySQL
...
EndOfMySQL
逃脱单个字符还将防止上述扩展。
编辑:请注意,此处 - doc的线不受文件名的生成(Globbing)!
我想在这种情况下的问题是您没有引用变量传递到 mysql :
echo $query | mysql database
应该是:
echo "$query" | mysql database
或更高:
printf '%sn' "$query" | mysql database
为什么不使用:
query='INSERT into tmp_table
SELECT * FROM table;'
printf '%sn' "$query" | mysql
或(如果您的shell支持 there-sinstrings , bash 支持它们的最新版本):
mysql <<< "$query"
防止*
和其他Glob Charcters扩展。禁用 globbing - 在您的之前使用 set -f
document
在此处逃脱了 docume 的任何字符的确意味着 no parameter expansion
, command substitution
, arithmetic expansion
或 pathname expansion
是执行的 - 但是, pathname expansion
具有
来自man bash
-
路径名扩展 - 在单词分开之后, *除非已设置
-f
选项,否则将每个单词扫描为字符 *,?和[。如果这些字符之一出现,则将单词视为模式,并用字母顺序排序的文件名列表匹配该模式。 -
内置commnds的外壳 Set
-f
- 禁用路径名扩展。
来自help set
-
-f
- 禁用文件名的生成(Globbing)。
如何将星号传递到Bash Heredoc?
这样做没有技巧 - 此处的文档可以使用星号。
这个问题是基于对症状的误解(在这里犯的一个简单错误)。
星号的问题与此处的DOC或cat
的执行无关。*
在echo $query
期间扩展。
您可以通过用tee temp.txt
替换cat
并查看生成文件的内容来证明自己。
但是,其他类型的扩展已处理(默认情况下),因此,如果您 did 想要展开星号,您可以做这样的事情:
SELECT $(echo *) FROM table
您可以将引号围绕Heredoc的名称,以完全禁用扩展:
cat <<'EndOfMySQL'
另请参阅:如何在bash脚本中写下Heredoc?