web-dev-qa-db-ja.com

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

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

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

より簡単/より良い方法はありますか?

13
Kerry Randolph

これを行う別の方法は、宣言するパラメーターに名前を付けてから実行することです。

{   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が空であるか、デフォルト値の設定が解除されている場合some_default$eightに割り当てられます。いずれの場合も、空が許容値である場合は、:または:-ステートメントから:=を削除できます。

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

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

...そして前の行は完全に省略されていますが、そのように変数を宣言すると永続的な値になることを示したかったので、2つのコマンドでそれを行いました。いずれの場合も、$eightはその複合パラメーター展開の最終値に設定されます。

getopts-堅牢なスクリプトの場合-コマンドを処理するための最良の方法であることがよくありますoptions。一方、位置パラメータは、ほとんどの場合、スクリプト内でオペランドを堅牢に処理するための最も簡単な手段です。

例えば:

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

出力

$eight = file008

そこには8番目のオペランドしか表示されていませんが、テストディレクトリから101個のオペランドが取得されています。

4
mikeserv

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

オプションとして最初の7つの7つのパラメーターのそれぞれがあり、それらがデフォルトで空の文字列になっている場合は、次のようにすることができます。

./foo bar

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

最後のX非オプション引数が最後のY引数とX-Yオプション引数の値であるようなものを実装しない限り、これらのいずれかを設定する場合は、7つの(現在は空の)文字列の前にオプション文字列を指定する必要があります。ただし、これは一般的な方法ではありません。通常、オプションは常にオプションであり、引数は引数であり、オプションの「挿入」の順序は自由です。

18
Anthon