bash は zsh の $@[2,$#] と同じです。

bash は zsh の $@[2,$#] と同じです。

(注:この質問の動機は、単にbashプログラミング知識を向上させるためのものです。)

bash対応する表現を知りたいです。zsh$@[2,$#]まっすぐ$@シェル関数(またはスクリプト)のコマンドライン引数の配列()の範囲を指定します。

(アドレス範囲をオンラインで見つけたすべてのソリューション$@bash間接的な$@アドレス指定はすべて中間変数に最初に割り当てる必要があるためです。以下の例を参照してください。)

具体的に言えば、bash次のテスト機能zshと同等のものは何ですか?

testfn () {
  printf '>%s<\n' $@[2,$#]
}

% testfn a b c d
>b<
>c<
>d<

上記のように、私が思いついた最も近い方法は次のとおりです。$@中間変数に割り当てる必要があります。

testfn () {
  holdargs=( $@ )
  printf '>%s<\n' "${holdargs[@]:1}"
}

中間変数を必要としないすべての試行はエラーのため失敗しますbad substitution

答え1

これは私にとって効果的です。

testfn () {
   printf '>%s<\n' "${@:2}"
}

例:

$ testfn a b c d
>b<
>c<
>d<

~からBash b 初心者ガイド

$@     Expands to the positional parameters, starting from one. When the 
       expansion occurs within double quotes, each parameter expands to a
       separate word.

位置パラメータセクションの表示バッシュハッカーウィキしかも広く使われているより多くの例と詳細については、セクションを参照してください。

これは通常二重引用符を使用する場合です$@"$@"それ以外の場合、"${@:2}"返された結果は二重引用符の結果になります。

$@配列要素には、次の表記法を使用してアクセスできます。

"${@:START:COUNT}"

「過剰使用」セクションからの抜粋

これにより、STARTから始めてCOUNT個の位置パラメータが展開されます。 COUNTは省略できます(${@:START})、この場合、STARTで始まるすべての場所引数が拡張されます。

要素が空ですか?

他の人は、上記の内容が空の要素を処理できないため、同じではないと指摘しました。私はBash 4.1.7を使っていますが、そうです。

例:

$ testfn "" a "" c d e
>a<
><
>c<
>d<
>e<

$ testfn '' a '*' c d e
>a<
>*<
>c<
>d<
>e<

$ testfn "" a " " c d e
>a<
> <
>c<
>d<
>e<

答え2

存在するzsh

printf '<%s>\n' ${@[2,$#]}

それは同じです

printf '<%s>\n' $@[2,-1]

null 以外の位置要素 2 を最後の要素まで印刷します。これは作成と同じです($# == 5の場合)。

printf '<%s>\n' $2 $3 $4 $5

だから:

$ set 1 2 '' '*' 5
$ printf '<%s>\n' $@[2,-1]
<2>
<*>
<5>

同等のものを得るには、bash次のものが必要です。

$ set 1 2 '' '*' 5
$ a=("$@")
$ IFS=; set -f
$ printf '<%s>\n' ${a[@]:1}
<2>
<*>
<5>

動作しないため、中間配列が必要です${@:2}(少なくとも4.2.45ではありません)。

もちろん、空であるかどうかにかかわらず、最初の要素を除くすべての要素が必要な場合は、次のように書く必要があります。

$ printf '<%s>\n' "$@[2,-1]"
<2>
<>
<*>
<5>

zsh一緒にする

$ printf '<%s>\n' "${@:2}"
<2>
<>
<*>
<5>

存在するbash

構文はzsh最後に含まれているので${array:first:n}(cshスタイルの修飾子と競合しない場合のみ)、上記のbash(実際にはksh)コードは最新のバージョンですzsh

${a[@]:1}との違いがある理由は、orとは逆に配列から位置をコピーするときと同様に、配列がリーンでインデックスが0から始まること${@:2}を覚えておく必要があります。bashzshcshrckshbash

${a[@]:4:5}インデックスが4以上の最初の5つの要素を返します。最初の要素$@のインデックスは 1( $1) で、 で定義された配列a=(...)の要素は 0 から始まるインデックスに設定されます。

まあ、それは完全に真実ではありません。で like は $# > 0 の場合にのみ while (引用符なし) のように拡張され、bash設定されていないか空でない場合にのみ可能です。これは私にバグのように聞こえます。では動作は異なりますが、再び一貫しています。"$@""$1" "$2" "$3" "$4" "$5""${@:0:1}""$0""$@""${@:1}"$@${@:1}$IFSksh

関連情報