#!/bin/bash
if [ $# -gt 0 ]; then
snum=( $@ )
echo $snum
fi
./testscript.sh 1234 4568
The Output of echo command is only などのスクリプトを実行するときに、1234
すべての位置パラメータの配列を構築していないと思いますか?
#!/bin/bash
if [ $# -gt 0 ]; then
snum="$@"
echo $snum
fi
./testscript.sh 1234 4568
出力を実行すると、次のようになります。1234 4568
snum=( $@ )
なぜ最初の位置パラメータのみが使用されるのか疑問に思います。
答え1
リストコンテキスト"$@"
(二重引用符を含む)で使用して取得します。リスト個別に引用された位置パラメータ。
スカラーコンテキスト"$*"
(二重引用符を含む)で使用して位置引数を連結します。単一文字列最初の文字$IFS
(通常はスペース)を区切り文字として使用します。
$@
引用符なしで(最初の例のように)または"$@"
スカラーコンテキストで(2番目の例のように)使用することはほとんど意味がありません。bash
シェルでスカラーコンテキストで使用する"$@"
ことは、最初の文字を空白に設定するのと同じです。"$*"
$IFS
使用するとsnum=( "$@" )
配列が作成されますsnum
。変数にアクセスすると、$snum
配列の最初の要素が得られます。実際にはアクセスと同じです${snum[0]}
。"${snum[@]}"
同様の方法で個別に参照される要素を提供するリストを使用してください"$@"
。を使用すると"${snum[*]}"
同等の結果が得られますが、"$*"
配列の場合ですsnum
。
snum
位置引数リストから配列を作成して空でない場合は、その配列を印刷すると仮定すると、次のようになります。
#!/bin/bash
snum=( "$@" )
if [ "${#snum[@]}" -gt 0 ]; then
printf '%s\n' "${snum[@]}"
fi
snum
スクリプトに引数が指定されると、要素は別々の行に印刷されます。
実行例:
bash-5.1$ ./script 1 2 3 "hello world" 4
1
2
3
hello world
4
このhello world
パラメータは単一のパラメータのままです。いいえ周囲の引用符を忘れた場合、これが発生します$@
。
コロンで区切られた単一の文字列の位置引数のリストを印刷します。文字列を変更して、位置パラメータ間にコロンを挿入します$IFS
。
#!/bin/bash
IFS=:
snum="$*"
if [ -n "$snum" ]; then
printf '%s\n' "$snum"
fi
違いは、snum
要素配列ではなく単一の文字列であることです。文字列が空でない場合、つまり空でない引数が 1 つ以上のスクリプトに指定されている場合、スクリプトは文字列を出力します。
snum
または、引き続き配列として使用されるように、最初の例を少し変更して、
#!/bin/bash
snum=( "$@" )
if [ "${#snum[@]}" -gt 0 ]; then
IFS=:
printf '%s\n' "${snum[*]}"
fi
実行例:
bash-5.1$ ./script 1 2 3 "hello world" 4
1:2:3:hello world:4
答え2
var=( values )
配列変数の割り当て
var=value
はスカラー変数の割り当てです(そして、次のようvar="$@"
にvar
位置引数とスペースを連結して割り当てられます)。一つスカラなので文字列です)
$var
配列の要素はインデックス0の要素に展開されます。これは${var[0]}
配列のすべての要素に必要なものと同じで、${var[@]}
Kornシェルからコピーされた誤ったデザインです。
また注:
- Split + glob演算子は、リストコンテキストで引用されていない引数拡張を保持しますが、これはほとんど望ましくありません。皮肉なことに、上記の引用文を追加する唯一の場所は、引用文を必要としない場所だけです。
echo
出力のランダムデータには使用できませんbash
。
希望する場所は次のとおりです。
#! /bin/bash -
print_space_separated() {
local IFS=' '
printf '%s\n' "$*"
}
if [ "$#" -gt 0 ]; then
snum=( "$@" )
print_space_separated "${snum[@]}"
fi
zsh
who の配列設計が の配列設計より近い場合は、次のことができます。csh
ksh
#! /bin/zsh -
if (( $# > 0 )) {
snum=( $argv )
print -r -- $snum
}
(それprint -r
自体はkshに由来)
ただし、引用符なしで配列拡張を配置すると、このシェルで引数拡張が発生したときに分割+globなしで空の要素が削除され続けます。これを保存するには、ksh構文が必要です。
#! /bin/zsh -
if (( $# > 0 )) {
snum=( "$@" )
print -r -- "${snum[@]}"
}
("${snum[@]}"
'に短縮することもできますが"$snum[@]"
)。
invar="$@"
またはには、var="${array[@]}"
inの最初の文字とスペースで連結された位置引数var
で構成される文字列が含まれます。 POSIX 指定されていない動作は、参照コンテキストとリストコンテキストでのみ使用されます。移植性の最初の文字に関連付けられた位置引数を取得するには、(リストまたは非リストのコンテキストで)を使用します。$IFS
zsh
bash
$@
$IFS
"$*"
配列要素を任意の文字列(の最初の文字を除く)に関連付けるには:のパラメータ$IFS
拡張j
フラグを使用します。これに相当するものはありません。持っています。zsh
${(j[that-string])array}
bash
fish
string join -- that-string $array