シェルスクリプトを作成していますが、スクリプトのn番目のパラメータを印刷する必要があります。
n=3
たとえば、十分なパラメータを使用してスクリプトが実行されるとします。今度はn
パラメータを印刷する必要があります$3
。
しかし、もしそうなら、n=2
私たちはパラメータを印刷します$2
。
私は文を使用したくありませんif
。次のようなことをしたい
echo $($n)
しかし、上記の方法は私が望む方法では機能しません。
答え1
さまざまなシェルから年代順に:
- csh(70年代後半):(
$argv[$n]
1991年以降はzshでも動作し、2005年以降はFishでも動作します) - zsh(1991):
$argv[n]
//(最後のものもyashでサポートされていますが、追加の中括弧を使用してください$@[n]
:/)$*[n]
${@[n]}
${*[n]}
- rc(90年代初頭):
$$n
/$*($n)
(es、akangaにも適用されます) - ksh93 (1993):
${@:n:1}
,${*:n:1}
(1996年からbashでもサポートされ、zshでもサポートされています)2010年から、cshスタイルの修飾子との競合が必要または回避されるように${@:$n:1}
するには、以下を参照してください。${@: n:1}
そこ"$*"
事件について) - バッシュ(1996):
${!n}
- ジッシュ(1999年):
${(P)n}
。
ksh93/bash/yashでは、少なくともリストコンテキストでパラメータ拡張を引用する必要があり、cshは信頼できるコードを書くのが難しいことに注意してください。
リストコンテキストとn番目の位置bash
引数が設定されていない場合は違いがあります。後者はまったく引数なしで拡張されますが、前者は空の要素に拡張されるためです。"${!n}"
"${@:n:1}"
Bourneなどのシェル(Bourneシェルは9番目のインデックスでは機能しないため、Bourneシェルではありません)で標準のPOSIX sh構文を使用して、次のこともできます。
eval "nth=\${$n}"
厳密にゼロより大きい整数の標準の10進表現を含まない場合でも、動作はすべて異なります。$n
これが真であると保証できない場合(1つではないeval
)、ほとんどを使用するとランダムなコマンド実行の脆弱性が発生します(唯一の例外はおそらく上記のrc
場合csh
です)。
zsh
また、(with echo -E - $argv[n]
)、yash
(with ECHO_STYLE=raw echo "${*[$n]}"
)、fish
(with echo -- $argv[$n]
)に加えてecho
任意のデータの出力には使用できません。printf '%s\n' ...
代わりに使用してください。)。
答え2
スクリプトに渡すパラメータは配列に格納されるため、目的の@
操作を実行する簡単な方法は次のとおりです。配列スライス、位置から始まるn
、長さ1:
#!/bin/bash
n=3
echo "Argument $n: ${@:n:1}"
いくつかのパラメータを使用してこのコマンドを実行すると、次の結果が得られます。
$ foo.sh a b c d e f
Argument 3: c
もともと要求した別のオプションは「間接拡張」です。
#!/bin/bash
n=3
echo "Argument $n: ${!n}"
これを実行してください:
$ foo.sh a b c d e f
Argument 3: c
答え3
変数間接参照を使用できます。
#!/bin/bash
n=3
echo "${!n}"
答え4
単純なポータブルシェル(bash依存関係なし)ソリューション(コマンドの潜在的な欠陥をモジュールとして、echo
置き換えることができますprintf
):
print_nth () {
shift "$1"
echo "$1"
}
次に、次のようにします。
print_nth "$n" "$@"