function foo() {
A=$@...
echo $A
}
foo bla "hello ppl"
我希望输出为:
“bla”“你好ppl”
我需要做什么而不是省略号?
答案 0 :(得分:23)
@msw有正确的想法(在问题的评论中)。但是,使用引号打印参数的另一个想法是:使用隐式迭代printf
:
foo() { printf '"%s" ' "$@"; echo ""; }
foo bla "hello ppl"
# => "bla" "hello ppl"
答案 1 :(得分:6)
使用参数替换添加“作为前缀和后缀:
function foo() {
A=("${@/#/\"}")
A=("${A[@]/%/\"}")
echo -e "${A[@]}"
}
foo bla "hello ppl" kkk 'ss ss'
输出
"bla" "hello ppl" "kkk" "ss ss"
答案 2 :(得分:3)
您可以使用“$ @”将每个参数视为一个单独的参数,然后循环遍历每个参数:
function foo() {
for i in "$@"
do
echo -n \"$i\"" "
done
echo
}
foo bla "hello ppl"
答案 3 :(得分:3)
function quote_args {
for i ; do
echo \""$i"\"
done
}
将其引用的参数放在每行一个,这通常是提供其他程序的最佳方式。您确实以您没有要求的形式获得输出:
$ quote_args this is\ a "test really"
"this"
"is a"
"test really"
但它可以很容易地转换,这是大多数shell调用更喜欢的习惯用法:
$ echo `quote_args this is\ a "test really"`
"this" "is a" "test really"
但除非它经过另一个eval
通过,额外的引号可能会搞砸了。也就是说,ls "is a file"
会在
is a file
$ ls `quote_args is\ a\ file`
会尝试列出您可能不想要的"is
,a
和file"
。
答案 4 :(得分:2)
不需要循环:
foo() { local saveIFS=$IFS; local IFS='"'; local a="${*/#/ \"}"; echo "$a"\"; IFS=$saveIFS; }
在这个简单的示例中不需要保存IFS
,尤其是在函数退出之前恢复它,因为使用了local
。但是,我将其包括在内,以防其他事情进入更改IFS
可能影响的函数。
示例运行:
$ foo a bcd "efg hij" k "lll mmm nnn " ooo " ppp qqq " rrr\ sss
"a" "bcd" "efg hij" "k" "lll mmm nnn " "ooo" " ppp qqq " "rrr sss"
答案 5 :(得分:1)
此时唯一的解决方案是尊重参数内的反斜杠和引号:
$ concatenate() { printf "%q"" " "$@"; echo ""; }
$ concatenate arg1 "arg2" "weird arg3\\\\\\bbut\" legal!"
arg1 arg2 weird\ arg3\\\\\\bbut\"\ legal\!
注意"%q"" " 强>
%q ARGUMENT以可以作为shell重用的格式打印 输入,转义不可打印的字符 建议POSIX $''语法。
特殊字符(\
,\b
退格,...)确实会被接收程序解释,即使未在终端输出中显示解释。
让我们测试一下:
# display.sh: Basic script to display the first 3 arguments passed
echo -e '#!/bin/bash'"\n"'echo -e "\$1=""$1"; echo -e "\$2=""$2"; echo -e "\$3=""$3"; sleep 2;' > display.sh
sudo chmod 755 display.sh
# Function to concatenate arguments as $ARGS
# and "evalutate" the command display.sh $ARGS
test_bash() { ARGS=$(concatenate "$@"); bash -c "./display.sh ""$ARGS"; }
# Test: Output is identical whatever the special characters
./display.sh arg1 arg2 arg3
test_bash arg1 arg2 arg3
更复杂的测试:
./display.sh arg1 "arg2-1:Y\b-2:Y\\b-3:Y\\\b-4:Y\\\\b-5:Y\\\\\b-6:Y\\\\\\b" "arg3-XY\bZ-\"-1:\-2:\\-3:\\\-4:\\\\-5:\\\\\-6:\\\\\\-"
test_bash arg1 "arg2-1:Y\b-2:Y\\b-3:Y\\\b-4:Y\\\\b-5:Y\\\\\b-6:Y\\\\\\b" "arg3-XY\bZ-\"-1:\-2:\\-3:\\\-4:\\\\-5:\\\\\-6:\\\\\\-"
在display.sh
中,我们使用echo -e
代替echo
或printf
来解释特殊字符。如果被调用的程序解释它们,这只是代表性的。
-e 启用反斜杠转义的解释
如果-e生效,则识别以下序列:
- \ backslash
- \ a alert(BEL)
- \ b退格
- 等
注意:\b
是退格符,因此它会删除示例中的Y.
请注意,此示例不能在实际代码中复制:
bash -c
和screen -X
请接受多个参数,因此无需使用连接:请参阅Can't seem to use bash -c option with arguments after the -c option string)。使用$0
时,请注意传递bash -c
的内容。感谢接受的答案和Danny Hong answer in"如何在双引号内避免双引号?"