入れ子になったパラメータの解析

入れ子になったパラメータの解析

スクリプトのパラメータを正しく解析できません。このシナリオは以下に説明されています。

最初のスクリプト(test2.sh):

#! /bin/sh
arg_part1="./test1.sh '123 789'"
arg_part2=456

#Option 1
${arg_part1} ${arg_part2} 

#Option 2
$("$arg_part1" arg_part2)

2番目のスクリプト(test1.sh):

#! /bin/sh
echo "Hello World $1 $2"

出力:

Hello World '123 789'
./test1.sh '123 789': No such file or directory

希望の出力:

Hello World 123 789 456

「123 789」は最初のパラメータとして扱われ、456は2番目のパラメータとして扱われるべきです。メモ:arg_part1を2つの異なる変数に分割するオプションはありません。

答え1

${arg_part1}引き続き Split+glob 演算子 (引用符のない sums ) を使用できますが、分割${arg_part2}には別の区切り文字を使用できます (一部の要素には基本区切り記号 (スペース) の 1 つが含まれているため)。また、glob部分を無効にしたいと思います。

#! /bin/sh -
arg_part1='./test1.sh|123 789'
arg_part2=456

IFS='|'  # split unquoted expansions on | instead of default SPC+TAB+NL
set -o noglob # disable the glob part (not that it would have any effect
              # in this particular case).

$arg_part1 $arg_part2 # invoke split+glob

# or since you're not intending to split $arg_part2
$arg_part1 "$arg_part2"

コードを保存するには、変数よりも関数が適していることがよくあります。

arg_part1() { ./test1.sh '123 789' "$@"; }
arg_part2=456

arg_part1 "$arg_part2"

そして分割+グローブ演算子を台無しにする必要もなく、危険なeval

答え2

eval私はあなたが「固定」され、arg_part1がコマンド文字列として再解釈され、次にコマンドと引数で解析されるようにここを使用する必要があると思います。

#! /bin/sh
arg_part1="./test1.sh '123 789'"
arg_part2=456
eval "${arg_part1}" "${arg_part2}"

出力:

Hello World 123 789 456

デバッグ出力:

$ sh -x test2.sh
+ arg_part1='./test1.sh '\''123 789'\'''
+ arg_part2=456
+ eval './test1.sh '\''123 789'\''' 456
++ ./test1.sh '123 789' 456
Hello World 123 789 456

内部的に参照したため、'123 789'test1.shの単一引数として表示されます$1

関連情報