假设我有一个非常简单的shell脚本'foo':
#!/bin/sh
echo $@
如果我这样调用它:
foo 1 2 3
很高兴地打印出来:
1 2 3
但是,假设我的一个参数是双引号并且包含空格:
foo 1 "this arg has whitespace" 3
foo愉快地打印:
1 this arg has whitespace 3
双引号被剥夺了!我知道shell认为它帮我一个忙,但是...我想得到原始版本的论点,不受shell解释的影响。有没有办法这样做?
答案 0 :(得分:7)
首先,您可能需要$@
的引用版本,即"$@"
。要感受差异,请尝试在字符串中放置多个空格。
其次,引号是shell语法的元素 - 它对你不利。为了保护它们,你需要逃避它们。例子:
foo 1 "\"this arg has whitespace\"" 3
foo 1 '"this arg has whitespace"' 3
答案 1 :(得分:3)
双重报价$ @:
#!/bin/sh
for ARG in "$@"
do
echo $ARG
done
然后:
foo 1 "this arg has whitespace" 3
会给你:
1
this arg has whitespace
3
答案 2 :(得分:3)
我要做的是引用所有带有空格的论据,这可能有助于你的案例。
for x in "${@}" ; do
# try to figure out if quoting was required for the $x
if [[ "$x" != "${x%[[:space:]]*}" ]]; then
x="\""$x"\""
fi
echo $x
_args=$_args" "$x
done
echo "All Cmd Args are: $_args"
答案 3 :(得分:2)
假设您处于更严格的设置中,并且您无法更改命令行,并通过转义双引号使其更加“友好”。例如:
example_script.sh argument_without_quotes "argument with quotes i cannot escape"
首先考虑在你的脚本中你无法判断一个参数是否带引号传递,因为shell剥离了它们。
所以你可以做的是为包含空格的参数重建双引号
此示例重建整个命令行,双引号具有空格的参数
#!/bin/sh
#initialize the variable that will contain the whole argument string
argList=""
#iterate on each argument
for arg in "$@"
do
#if an argument contains a white space, enclose it in double quotes and append to the list
#otherwise simply append the argument to the list
if echo $arg | grep -q " "; then
argList="$argList \"$arg\""
else
argList="$argList $arg"
fi
done
#remove a possible trailing space at the beginning of the list
argList=$(echo $argList | sed 's/^ *//')
#pass your argument list WITH QUOTES
echo "my_executable" $argList
#my_executable $argList
请注意此限制。如果你运行这个例子
example_script.sh "argument with spaces" argument_without_spaces "argument_doublequoted_but_without_spaces"
你会得到这个输出
my_executable "argument with spaces" argument_without_spaces argument_doublequoted_but_without_spaces
注意最后一个参数:因为它没有空格,所以它没有再用双引号括起来,但这应该不是问题。
答案 4 :(得分:1)
你需要引用引号:
foo 1 "\"this arg has whitespace\"" 3
或(更简单地说)
foo 1 '"this arg has whitespace"' 3
您需要引用双引号以确保在解析单词参数时shell不会删除它们。