我发现当将文本写成另一个程序的输入时,任何在预期文本中双引号中的命令替换都会被shell解释和扩展。
答案这里中的链接指出,单引号可用于防止参数展开或命令替换。但是,我发现在单引号中包含命令替换也不能阻止shell展开命令替换。
如何防止shell解释作为文本而不是要执行的命令的替换命令?
$ echo "`wc -l *`"尝试计算当前目录中所有文件中的行数。
$ echo "'`wc -l *`'"相同的结果,即计算当前目录中所有文件中的行数。
更新从这个演示中我发现问题似乎是我引用了单引号。我认为在双引号中包含单引号和` (回勾),保留字面意思 (即取消)单引号,但不保留引入命令替换的反引号(即回勾)的字面意义。
在我的用例中,需要引用另一个命令的输入。这个文档说:
单引号不能出现在单引号中。
当单引号命令替换在(双)引号字符串内时,如何防止单引号命令替换被展开?除了使用反斜杠转义之外,还应该有一种方法来完成它。
在一个程序中,我使用的唯一方法是将任务描述拆分成不同的行,将描述用双引号括起来:
$ task add "first line doesn\'t say much
Second line says a lot but part of this line does not appear in the resulting description 'truncate -s0 !(temp_file | temp_dir)' truncates all files to 0 bytes as shown by: '`wc -l *`'"由此产生的说明:
first line doesn\ -s0 !(temp_file | temp_dir)' truncates all files to 0 bytes as shown by: 0 file1 10 file2 0 directory1 0 directory2 502 file3 123 file4 162 file5 0 directory3如你所见
't say much
Second line says a lot but part of this line does not appear in the resulting description 'truncate将'wc -l *'解释为命令替换,从而将当前目录中所有文件的行数作为描述的一部分包括在内。
是什么原因导致shell移除task在\ (反斜杠)和-s之间的部分参数,以及如何防止shell解释上面单引号的命令替换(即'`wc -l *`')?
发布于 2019-07-31 05:53:12
在这里(加了行符),
$ task add "first line doesn\'t say much
Second line says a lot but part of this line does not appear in the
resulting description 'truncate -s0 !(temp_file | temp_dir)' truncates
all files to 0 bytes as shown by: '`wc -l *`'"整个字符串都是双引号,因此命令替换和其他扩展将在那里运行。这种情况发生在shell中,在task看到该字符串之前,您需要使用反斜杠或将该部分放在单引号中来防止它。
例如。
$ printf "%s\n" "...shown by: '\`wc -l *\`'"
...shown by: '`wc -l *`'所以,
task add "...shown by: '\`wc -l *\`'"将字符串...shown by: '`wc -l *`'传递给task。这取决于它是怎么做的。
如果您不想使用反斜杠,下面是将其放入单引号的方法:
# aaaaaaaaaaaaaaaaBBBBBBBBBBBaaa
$ printf "%s\n" "...shown by: '"'`wc -l *`'"'"
...shown by: '`wc -l *`'( a's标记双引号,B's表示单引号。它们只是在shell命令行上连在一起。文字单引号在双引号内。)
至于单引号和反斜杠,您不需要在双引号中转义单引号,实际上反斜杠仍然存在:
$ printf "%s\n" "foo'bar"
foo'bar
$ printf "%s\n" "foo\'bar"
foo\'bar从您所显示的情况来看,task似乎至少从参数中删除了第一个单引号字符串(加上后面的一个单词,因为删除的部分是't say much ... 'truncate)。
shell将而不是这样做,这很好:
$ printf "%s\n" "a 'quoted string' to test"
a 'quoted string' to test是什么导致shell移除
task在\(反斜杠)和-s之间的参数部分,
很可能不是贝壳干的。
如何防止shell解释上述单引号命令替换(即
'`wc -l *`')?
它不是单引号,而是双引号,旁边是单引号。
发布于 2019-07-29 21:38:11
使用单引号强引用:
printf '%s\n' '`wc -l *`'如果希望在传递给printf的参数中也包括单引号,则需要对'本身使用不同的引号,例如:
printf '%s\n' '`wc -l *` and a '"'"' character'或者:
printf '%s\n' '`wc -l *` and a '\'' character'其他选择包括在双引号中使用反斜杠转义`:
printf '%s\n' "\`wc -l *\` and a ' character"或者让`是某些扩展的结果:
backtick='`'
printf '%s\n' "${backtick}wc -l *${backtick} and a ' character"还请注意:
cat << 'EOF'
`wc -l *` and a ' character and a " character
EOF输出任意文本而不必担心引用(注意第一个EOF周围的引号)。
你也可以:
var=$(cat << 'EOF'
echo '`wc -l *`'
EOF
)使用ksh93或mksh,您可以将其优化为:
var=$(<<'EOF'
echo '`wc -l *`'
EOF
)(也可以在zsh中工作,但仍然在子still中运行cat ),以便$var包含字面意义上的echo '`wc -l *`'。
在fish外壳中,可以使用\'将'嵌入到'...'中:
printf '%s\n' '`wc -l *` and a \' character'但是无论如何,`在那里并不特别,所以:
printf '%s\n' "`wc -l *` and a ' character"也能起作用。
在rc、es或zsh -o rcquotes中,您可以使用''在'...'中插入一个D29:
printf '%s\n' '`wc -l *` and a '' character'有关更多详细信息,请参阅如何使用一个特殊的字符作为一个正常的?。
发布于 2019-07-29 21:14:27
您可以使用反斜杠转义反斜杠,如下所示:
echo "\`wc -l *\`"https://unix.stackexchange.com/questions/532811
复制相似问题