bash中带引号的Shell引用
我想实现一个bash函数,该函数将其参数作为命令运行,同时(可能是可选的)在之前打印命令。请考虑安装脚本或测试运行程序脚本 只是使用bash中带引号的Shell引用,bash,escaping,printf,Bash,Escaping,Printf,我想实现一个bash函数,该函数将其参数作为命令运行,同时(可能是可选的)在之前打印命令。请考虑安装脚本或测试运行程序脚本 只是使用 function run () { echo "Running $@" "$@" } 不允许我将调用与运行foo arg1 arg2和运行foo“arg1 arg2”区分开来,因此我需要正确地转义参数 到目前为止,我最好的机会是 function run () { echo -n "Running" printf " %q" "$
function run () {
echo "Running $@"
"$@"
}
不允许我将调用与运行foo arg1 arg2
和运行foo“arg1 arg2”
区分开来,因此我需要正确地转义参数
到目前为止,我最好的机会是
function run () {
echo -n "Running"
printf " %q" "$@"
echo
"$@"
}
有效的方法是:
$ run echo "one_argument" "second argument" argument\"with\'quotes
Running echo one_argument second\ argument argument\"with\'quotes
one_argument second argument argument"with'quotes
但不是很优雅。我如何才能实现的输出
$ run echo "one_argument" "second argument" argument\"with\'quotes
Running echo one_argument "second argument" "argument\"with'quotes"
one_argument second argument argument"with'quotes
i、 e.我如何才能使
printf
在需要引用的参数周围加上引号,并正确地转义其中的引号,以便输出可以正确地复制粘贴?我认为没有一个优雅的解决方案可以满足您的需要,因为“$@”
在任何命令看到它之前由bash处理。您必须手动重新构造命令行:
#!/bin/bash
function run() {
echo -n "Running:"
for arg in "$@"; do
arg="$(sed 's/"/\\&/g' <<<$arg)"
[[ $arg =~ [[:space:]\\\'] ]] && arg=\"arg\"
echo -n " $arg"
done
echo ""
"$@"
}
run "$@"
我认为没有一个优雅的解决方案可以满足您的需求,因为在任何命令看到它之前,“$@”
由bash
处理。您必须手动重新构造命令行:
#!/bin/bash
function run() {
echo -n "Running:"
for arg in "$@"; do
arg="$(sed 's/"/\\&/g' <<<$arg)"
[[ $arg =~ [[:space:]\\\'] ]] && arg=\"arg\"
echo -n " $arg"
done
echo ""
"$@"
}
run "$@"
这将引用所有内容:
run() {
printf "Running:"
for arg; do
printf ' "%s"' "${arg//\"/\\\"}"
done
echo
"$@"
}
run echo "one_argument" "second argument" argument\"with\'quotes
此版本仅引用包含双引号或空格的参数:
run() {
local fmt arg
printf "Running:"
for arg; do
[[ $arg == *[\"[:space:]]* ]] && fmt=' "%s"' || fmt=" %s"
printf "$fmt" "${arg//\"/\\\"}"
done
echo
"$@"
}
run echo "one_argument" "second argument" argument\"with\'quotes
这将引用所有内容:
run() {
printf "Running:"
for arg; do
printf ' "%s"' "${arg//\"/\\\"}"
done
echo
"$@"
}
run echo "one_argument" "second argument" argument\"with\'quotes
此版本仅引用包含双引号或空格的参数:
run() {
local fmt arg
printf "Running:"
for arg; do
[[ $arg == *[\"[:space:]]* ]] && fmt=' "%s"' || fmt=" %s"
printf "$fmt" "${arg//\"/\\\"}"
done
echo
"$@"
}
run echo "one_argument" "second argument" argument\"with\'quotes
你能不能把所有的论点都用引号括起来,而不仅仅是那些需要的论点?您只需在所有参数周围转义双引号,如下所示:tldp.org/LDP/Bash-初学者-Guide/html/sect_03_03.htmlh这将是丑陋的,如果参数包含引号,则不正确。用于调试输出,虽然没有那么严重,但我仍然希望输出是正确的。啊,我明白了。很抱歉,我对BASH的了解还不足以帮助你克服这个问题。看看这个:在参数中也没有转义引号。我想我应该详细说明我的问题。你能不能在所有的论点周围加上引号,而不仅仅是那些需要的论点?您只需在所有参数周围转义双引号,如下所示:tldp.org/LDP/Bash-初学者-Guide/html/sect_03_03.htmlh这将是丑陋的,如果参数包含引号,则不正确。用于调试输出,虽然没有那么严重,但我仍然希望输出是正确的。啊,我明白了。很抱歉,我对BASH的了解还不足以帮助你克服这个问题。看看这个:在参数中也没有转义引号。我想我应该详细说明我的问题。这看起来与评论中@MohammadJavadNaderi的链接非常相似;它似乎无法处理引用特殊字符,例如“
本身。您不能将参数移开--打印后您将无法执行命令!此外,正则表达式将匹配字符{“a”、“c”、“e”、“p”、“s”、“:”}中的一个--您需要[:space:]
@glennjackman这就是我因测试不足而得到的结果。感谢大家的提醒。修复了。这看起来与评论中的@MohammadJavadNaderi链接非常相似;它似乎无法处理引用特殊字符,如”
本身。您不能将
参数移开--打印后将无法执行该命令!此外,正则表达式将匹配字符{“a”、“c”、“e”、“p”、“s”和“:”}中的一个--您需要[[:space:]
@glennjackman这是我在测试不足时得到的结果。谢谢你的提醒。固定的。
Running: echo one_argument "second argument" "argument\"with'quotes"
one_argument second argument argument"with'quotes