Ste*_*nny 5 shell posix quoting variable
我想将此命令放入稍后运行的文件中:
ln -s "$xr"/ya.txt ~
Run Code Online (Sandbox Code Playgroud)
我可以用(1)做到这一点:
cat > zu.sh <<eof
ln -s "$xr"/ya.txt ~
eof
Run Code Online (Sandbox Code Playgroud)
或(2):
printf 'ln -s "%s"/ya.txt ~\n' "$xr" > zu.sh
Run Code Online (Sandbox Code Playgroud)
或(3):
echo "ln -s '$xr'/ya.txt ~" > zu.sh
Run Code Online (Sandbox Code Playgroud)
或(4):
printf 'ln -s %q/ya.txt ~\n' "$xr" > zu.sh
Run Code Online (Sandbox Code Playgroud)
或 (5):
printf 'ln -s "%s"/ya.txt ~\n' "${xr//\"/\\\"}"
Run Code Online (Sandbox Code Playgroud)
然而,每个解决方案都是有问题的。如果 (1) 或 (2) 中的变量包含双引号,它们将失败;如果 (3) 中的变量包含单引号,则会失败。(4) 很好,但不是由 POSIX 定义的。(5) 是好的但是是 一种 Bashism。看起来最好的选择是使用 (1) 或 (2) 并转义变量中的任何双引号,但这可以用另一种方式完成吗?
我认为这是安全的:
\n\nesc() {\n printf "%s\\n" "$1" | sed -e "s/\'/\'\\"\'\\"\'/g" -e "1s/^/\'/" -e "\\$s/\\$/\'/"\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n它单引号字符串,因此输入字符串中的任何$
, `
, \\
, 和"
都无关紧要,并将任何现有\'
字符转换为\'"\'"\'
(即结束单引号,双引号单独的单引号,然后 re\xc3 \xabnter 单引号)。
在那里使用$(...)
命令替换是很诱人的,只不过它会吃掉输入中任何尾随的换行符。相反,左引号和右引号是由第二个和第三个sed
脚本本身插入到第一行的开头和最后一行的末尾。任何嵌入的换行符都保持原始状态,这很好。
输出适合复制回 shell,即使是在我能发明的最病态的情况下(首先使用Bash ANSI-C 引用创建测试字符串,但之后不创建):$\'...\'
esc() {\n printf "%s\\n" "$1" | sed -e "s/\'/\'\\"\'\\"\'/g" -e "1s/^/\'/" -e "\\$s/\\$/\'/"\n}\n
Run Code Online (Sandbox Code Playgroud)\n\nxr=$(esc "$xr")
将其放入变量中,然后在此处文档或其他地方的普通替换中使用它是安全的。