因此,我可以很高兴地在bash数组中建立一个命令行,然后用引号将其执行并获得每个引号的引号:
declare -a cmd_args
cmd_args=("-p" "dir path/with spaces")
mkdir "${cmd_args[@]}"
echo dir*/*
Run Code Online (Sandbox Code Playgroud)
但是,如何以一种有意义的方式将其回显到屏幕上,即向用户显示他们可以键入的命令,或者可以将其保存在日志文件中以备将来参考?所有这些看起来(基本上)是相同的:
echo runnimg mkdir with arguments ${cmd_args[@]}
echo runnimg mkdir with arguments "${cmd_args[@]}"
echo "runnimg mkdir with arguments '${cmd_args[@]}'"
echo "runnimg mkdir with arguments '${cmd_args[*]}'"
==> runnimg mkdir with arguments '-p dir path/with spaces'
Run Code Online (Sandbox Code Playgroud)
这显然是错误的命令。这并没有向用户显示他们可以键入的命令,或者我可以保留在日志文件中并在将来的日期重现的命令。我想看看:
runnimg mkdir with arguments '"-p" "dir path/with spaces"'
Run Code Online (Sandbox Code Playgroud)
我考虑过使用cat<<EOF:
cat<<EOF
"${cmd_args[@]}"
EOF
Run Code Online (Sandbox Code Playgroud)
但实际上,这会在整个参数列表中产生一个很大的报价!这里有什么?这怎么可能永远是我的意图是什么?如果是这样,那我就有"${cmd_args[*]}"。
这就是挑战。以用户可以说“是的,这是正确的命令”的方式打印命令。
对那些说“%p \ n”的人表示抱歉,但是对于日志文件来说这可能没问题,但是返回并对其进行“毫不含糊地”格式化以重新测试该命令仍然很麻烦,但它确实不够好交互式“这是命令反馈给用户”。
也许已经有一个答案,但是如果是这样,那么所有“总是引用您的论据”类型的答案就会淹没它。
如果要打印带有引号的参数列表,而不管引号是否合适:
printf '"%s" ' "${cmd_args[@]}"
Run Code Online (Sandbox Code Playgroud)
如果要仅在需要时打印带引号或转义的参数列表:
printf '%q ' "${cmd_args[@]}"
Run Code Online (Sandbox Code Playgroud)
要做到这一点:
printf 'runnimg mkdir with arguments:'
printf ' %q' "${cmd_args[@]}"
Run Code Online (Sandbox Code Playgroud)
一个dash kshPOSIX兼容的外壳执行:
#!/usr/bin/env dash
#cmd_args=("-p" "dir path/with spaces")
# dash and POSIX shell don't have arrays
# but support setting the arguments like this:
set -- -p "dir path/with spaces"
printf 'runnimg mkdir with arguments:'
# dash built-in printf does not know about %q format,
# but system command printf does.
env printf ' %q' "$@"
echo
mkdir "$@"
Run Code Online (Sandbox Code Playgroud)