親コマンドの引数を子コマンドに渡す

シェルスクリプトで、親が受け取った引数を、そのまま子コマンドに渡したい場合は、"$@"を使えばいいらしい。

#! /bin/sh
# file: parent

echo "== $0 =="
for a; do
    echo "arg: ${a}"
done

./child "$@"
./child $@
#! /bin/sh 
# file: child

echo ""
echo "== $0 =="
for a; do
    echo "arg: ${a}"
done

実行

$ ./parent "1 2" a "" b
== ./parent ==
arg: 1 2
arg: a
arg: 
arg: b

== ./child ==  # "$@"で渡した場合: 正しい
arg: 1 2
arg: a
arg:
arg: b

== ./child ==  # $@で渡した場合: 間違い
arg: 1
arg: 2
arg: a
arg: b


渡す引数を少し加工したい場合は、区切り文字(IFS変数)を変更して(引数を連結して)子コマンドを呼び出すのが簡単。 もっといい方法があるかもしれない...

#! /bin/sh
# file: parent2

# 1番目と4番目の引数を'<>'で囲って渡したい

## 単純に空白で連結して渡してみる
args="<$1> <$4>"
./child "$args"
./child $args

## 区切り文字を変更
# 改行とベル文字
DELIM='
^G' 

IFS=$DELIM
args="<$1>${DELIM}<$4>"
./child $args

実行

$ ./parent2 "1 2" a "" b

== ./child ==  
arg: <1 2> <b>

== ./child ==
arg: <1
arg: 2>
arg: <b>

== ./child ==  # 区切り文字を変更して渡したもの
arg: <1 2>
arg: <b>

上の場合だと、改行文字とベル文字が、もともとの引数の中に入っていた場合、変な場所で引数が分割されることになるが、どちらもあまり使われることはないと思うので、多分問題はない。