我有一个 shell 变量(我们称之为x),其中包含一个带有 shell 元字符的字符串。例如,我可能有
abc "def's" ghi
Run Code Online (Sandbox Code Playgroud)
由设置
x='abc "def'\''s" ghi'
Run Code Online (Sandbox Code Playgroud)
我想从该字符串构建一个 shell 命令(存储在文件中,而不是执行)。我有什么选择?
echo "prog $x" >>file # Doesn't work
echo "prog '$x'" >>file # Doesn't work
echo "prog \"$x\"" >>file # Doesn't work
Run Code Online (Sandbox Code Playgroud)
目前的解决方案使用sed
y=`echo "$x" | sed 's/\([^a-zA-Z0-9._\-\/]\)/\\\\\1/g'`
echo "prog $y" >>file
Run Code Online (Sandbox Code Playgroud)
输出如下(尽管等效输出也是可以接受的):
prog abc\ \ \"def\'s\"\ \ ghi
Run Code Online (Sandbox Code Playgroud)
问题是需要这样做的地方数量正在增加。有人有更好的解决方案吗?
笔记:
sh(与 相对bash)并且任何内容都sh可以合理地别名(例如bash在sh仿真模式下)。perl是不可接受的,但使用随处可见的其他 UNIX 工具可能是可接受的。sh有功能。
# to_shell_lit() - Creates a shell literal
# Usage: printf '%s\n' "...$( to_shell_lit "..." )..."
to_shell_lit() {
printf \'
printf %s "$1" | sed "s/'/'\\\\''/g"
printf \'
}
Run Code Online (Sandbox Code Playgroud)
测试:
$ x='abc "def'\''s" ghi'
$ printf '%s\n' "$x"
abc "def's" ghi
$ printf '%s\n' "prog `to_shell_lit "$x"`"
prog 'abc "def'\''s" ghi'
$ printf '%s\n' "prog $( to_shell_lit "`pwd`" )"
prog '/home/ikegami/foo bar'
Run Code Online (Sandbox Code Playgroud)
$ printf '%s\n' "$( to_shell_lit "a'b" )"
'a'\''b'
$ printf '%s\n' "$( to_shell_lit '-n' )"
'-n'
$ printf '%s\n' "$( to_shell_lit '\\' )"
'\\'
$ printf '%s\n' "$( to_shell_lit 'foo
bar' )"
'foo
bar'
Run Code Online (Sandbox Code Playgroud)
带有多个参数的版本:
# to_shell_lit() - Creates a shell literal
# Usage: printf '%s\n' "$( to_shell_lit "..." "..." "..." )"
to_shell_lit() {
local prefix=''
local p
for p in "$@" ; do
printf "$prefix"\'
printf %s "$p" | sed "s/'/'\\\\''/g"
printf \'
prefix=' '
done
}
Run Code Online (Sandbox Code Playgroud)