我有这个简单的脚本来打印它收到的内容然后退出:
IFS="|${IFS}";
echo "$# parameters";
echo Using '$*';
for p in $*;
do
echo "[$p]";
done;
echo Using '"$*"';
for p in "$*";
do
echo "[$p]";
done;
echo Using '$@';
for p in $@;
do
echo "[$p]";
done;
echo Using '"$@"';
for p in "$@";
do
echo "[$p]";
done
如果我执行:./echoparams This is a "test target"
它将打印出来:
4 parameters
Using $*
[This]
[is]
[a]
[Test]
[target]
Using "$*"
[This|is|a|Test target]
Using $@
[This]
[is]
[a]
[Test]
[target]
Using "$@"
[This]
[is]
[a]
[Test target]
问题:
我有一个外部程序(我无法修改)将其传递到我的脚本中,但是当它执行时会打印出来:
1 parameters
Using $*
[This]
[is]
[a]
["test]
[target"]
Using "$*"
[This is a "test target"]
Using $@
[This]
[is]
[a]
["test]
[target"]
Using "$@"
[This is a "test target"]
我有一种预感,它实际上是将"This is a \"test target\""
传递给脚本。 如何使用此“一个参数”并将其设为“多个参数”,但仍然尊重组合词(带有引号)?
答案 0 :(得分:3)
尝试:
eval set "$@"
或(如果它可能以shell选项开头,则更安全):
eval set -- "$@"
之后,您应该可以使用"$@"
。
与所有eval
一样,这有各种各样的危险。 : - )
危险的例子:
$ set '`ls`'
$ eval set -- "$@"
$ echo $#
28
$ echo "$1"
COPYRIGHT
编辑:这是一个protect
shell函数和一个使用它的例子。我不确定我是否能够抵御一切,但它有两个明显的例子:
#! /usr/bin/env bash
protect()
{
local quoted
quoted="${1//$/\\\$}"
quoted="${quoted//\`/\\\`}"
# use printf instead of echo in case $1 is (eg) -n
printf %s "$quoted"
}
foo=expanded
set -- '-e -n $foo `ls` "bar baz"'
eval set -- "$@"
echo "without protect, \$# is $#:"
for arg do echo "[$arg]"; done
set -- '-e -n $foo `ls` "bar baz"'
eval set -- $(protect "$@")
echo "with protect, \$# is $#"
for arg do echo "[$arg]"; done
当我运行它时:
without protect, $# is 46:
[-e]
[-n]
[expanded]
[OUT]
[a.py]
[ast_ex.py]
---snipped remaining ls output for space reasons---
[bar baz]
with protect, $# is 5
[-e]
[-n]
[$foo]
[`ls`]
[bar baz]
如果其他字符需要引用,很明显如何将它们添加到protect
。