4

受け取ったものを出力して終了する単純なスクリプトがあります。

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\""実際にスクリプト に渡されているという予感があります。この「1つのパラメーター」を「複数のパラメーター」にするにはどうすればよいですか?

4

1 に答える 1

3

試す:

eval set "$@"

または(シェルオプションで始まる方が安全です):

eval set -- "$@"

その後、使用できるようになるはずです"$@"

すべてevalの s と同様に、これにはあらゆる種類の危険があります。:-)

危険の例:

$ set '`ls`'
$ eval set -- "$@"
$ echo $#
28
$ echo "$1"
COPYRIGHT

編集: これはprotectシェル関数とその使用例です。すべてに対して保護したかどうかはわかりませんが、次の 2 つの明らかなケースがあります。

#! /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です。

于 2013-08-28T18:00:56.030 に答える