[英]How to pass an asterisk into bash heredoc?
I execute a MySQL statement with an asterisk from within a bash shell:我从 bash shell 中执行带有星号的 MySQL 语句:
query=`cat <<EndOfMySQL
INSERT tmp_table
SELECT * FROM table
;
EndOfMySQL
`
echo $query
echo $query | mysql database
The problem is that the asterisk is replaced by the list of files in the current directory and the query becomes erroneous.问题是星号被当前目录中的文件列表替换,查询变得错误。 How to avoid this behavior?
如何避免这种行为? It doesn't matter whether I use backticks or
$()
.使用反引号还是
$()
都没有关系。 I'd expect some escape sequence like \*
, but at least this one doesn't work.我希望有一些像
\*
这样的转义序列,但至少这个是行不通的。
You could prevent parameter expansion, command substitution, and arithmetic expansion in a here-document by quoting the delimiter string:您可以通过引用分隔符字符串来防止此处文档中的参数扩展、命令替换和算术扩展:
... <<\EndOfMySQL
...
EndOfMySQL
Escaping the single character will also prevent the expansions listed above.转义单个字符也会阻止上面列出的扩展。
Edit: Note that the lines of the here-doc are no subject to filename generation (globbing)!编辑:请注意,here-doc 的行不受文件名生成(通配)的约束!
I suppose that the problem in this case is that you didn't quote the variable passed to mysql :我想这种情况下的问题是你没有引用传递给mysql的变量:
echo $query | mysql database
should be:应该:
echo "$query" | mysql database
or better yet:或者更好:
printf '%s\n' "$query" | mysql database
Why don't you use:你为什么不使用:
query='INSERT into tmp_table
SELECT * FROM table;'
printf '%s\n' "$query" | mysql
or (if your shell supports here-strings , recent versions of bash support them):或者(如果你的 shell 支持here-strings ,最新版本的bash支持它们):
mysql <<< "$query"
To prevent *
and other glob charcters from expanding.防止
*
和其他 glob 字符扩展。 disable globbing –use set -f
before your Here Document禁用globbing——在你的Here Document之前使用
set -f
Escaping any of the characters of the delimiter of Here Document does mean that No parameter expansion
, command substitution
, arithmetic expansion
, or pathname expansion
is performed – However, pathname expansion
has a caveat !转义Here Document定界符的任何字符确实意味着不执行
parameter expansion
、 command substitution
、 arithmetic expansion
或pathname expansion
——但是, pathname expansion
有一个警告!
From man bash
来自
man bash
Pathname Expansion — After word splitting, *unless the -f
option has been set, bash scans each word for the characters *, ?, and [.路径名扩展——分词后,*除非设置了
-f
选项,bash 会扫描每个词中的字符 *、? 和 [。 If one of these characters appears, then the word is regarded as a pattern, and replaced with an alphabetically sorted list of file names matching the pattern.如果出现这些字符之一,则该词被视为一种模式,并替换为按字母顺序排列的与该模式匹配的文件名列表。
Shell Builtin Commnds — set -f
– Disable pathname expansion. Shell 内置命令 — set
-f
– 禁用路径名扩展。
From help set
来自
help set
-f
– Disable file name generation (globbing). -f
– 禁用文件名生成(通配)。How to pass an asterisk into bash heredoc?
如何将星号传递给 bash heredoc?
There is no trick to doing this -- the here document works fine with an asterisk.这样做没有什么诀窍——这里的文档在带星号的情况下效果很好。
This question is based on a misinterpretation of the symptoms (which is an easy mistake to make here).这个问题是基于对症状的误解(这是一个很容易犯的错误)。
The issue with the asterisk has nothing to do with the here-doc or the execution of cat
.星号的问题与 here-doc 或
cat
的执行无关。 The *
is expanded during echo $query
. *
在echo $query
期间扩展。
You could prove this to yourself by replacing cat
with tee temp.txt
, and reviewing the contents of the generated file.您可以通过将
cat
替换为tee temp.txt
并查看生成文件的内容来向自己证明这一点。
However, other types of expansion are processed (by default), so if you did want to expand the asterisk, you could do something like this:但是,会处理其他类型的扩展(默认情况下),因此如果您确实想扩展星号,您可以这样做:
SELECT $(echo *) FROM table
You can put quotes around the name of the heredoc to disable expansion altogether:您可以在 heredoc 的名称周围加上引号以完全禁用扩展:
cat <<'EndOfMySQL'
See also: How can I write a heredoc to a file in Bash script?另请参阅:如何将 heredoc 写入 Bash 脚本中的文件?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.