シェルスクリプトを実行するときに順番に入力しなくても特定の位置引数を渡すことはできますか?

シェルスクリプトを実行するときに順番に入力しなくても特定の位置引数を渡すことはできますか?

たとえば、10個のパラメータを必要とする./fooスクリプトがあり、8番目のパラメータのみを渡したいとします。現在私が知っている唯一の方法は次のとおりです。

./foo '' '' '' '' '' '' '' 'bar'

より簡単でより良い方法がありますか?

答え1

スクリプトを変更できると仮定すると、必須パラメータ(パラメータ)の代わりにオプションのパラメータ(オプション)を使用することを検討する必要があります。

最初の7つのパラメータをそれぞれオプションとして使用し、デフォルトで空の文字列を使用する場合は、次のことができます。

./foo bar

使用する場合POSIX互換シェル使用できるgetoptsユーティリティまたはプログラムgetoptbash- ほとんどのシェルと同様に - 組み込みgetoptsで提供されます。どちらも自分のコマンドラインパーサーを実行するよりも簡単です。

最後のX非オプションパラメータなどを実装しない限り、最後のYパラメータの値とオプション文字列を提供します。しかし、これは一般的な慣行ではなく、通常、オプションは常にオプションであり、引数は常に引数であり、オプションが「挿入」される順序は自由です。

答え2

これを行うもう1つの方法は、宣言したいパラメータの名前を指定し、次のことです。

{   cat >./foo 
    chmod +x ./foo
    eight=declared ./foo
    eight=declared_and_preferred \
        ./foo 1 2 3 4 5 6 7 8
    ./foo 1 2 3 4 5 6 7 8
    ./foo
} <<\SCRIPT
#!/usr/bin/sh
: ${eight:=${8:-some_default}}
printf '$eight = %s\n' "$eight"
#END
SCRIPT

出力

$eight = declared
$eight = declared_and_preferred
$eight = 8
$eight = some_default

上記の例では、明示的に宣言された環境変数がコマンドライン引数よりも優先されますが、環境変数が空であるか設定されていない場合は、コマンドライン引数が使用されます。両側が8番位置にあるときそして環境変数が$eight空であるか、デフォルト値が設定されていません。一部のデフォルトどちらの場合も、nullが$eight許容値の場合は:orステートメントから削除できます。:-:=

この変数は$eight次のように設定することもできます。

printf '$eight = %s\n' "${eight:=${8:-some_default}}"

...前の行は完全に省略されていますが、このように変数を宣言すると永続的な値が生成されることを証明したいので、2つのコマンドを使用して行いました。どちらも$eight複合パラメータ拡張の最終値に設定されます。

getopts- 強力なスクリプトの場合 - コマンドを処理する最良の方法であることがよくあります。オプション。一方、位置パラメータはほぼ常に強力に処理する最も簡単な方法です。オペランドスクリプトから。

たとえば、

touch file$(seq -ws\ file 100)
./foo *

出力

$eight = file008

ここでは8番目のオペランドしか見えませんが、私のテストディレクトリには101個あります。

関連情報