関数を作成しようとしており、うまく動作する例を見つけたと思いますが、その背後にあるロジックをすべて理解しているわけではありません。
もっと具体的に言うと、「while」行で、test とは何で、何をするのかを説明していただけますか? $# とは何ですか (# はコメント文字ではありませんか?)、-gt 0 パラメータはどこから来るのですか? while のマニュアル ページでは見つけられませんでした。
次に例を示します。
function my_function()
{
while test $# -gt 0
do
$
echo "$1"
shift
done
}
ありがとう。
答え1
#
それ自体は間違いなくコメントですが、$#
関数に渡されるパラメータの数が含まれます。
test
は、さまざまなテストを実行できるプログラムです。たとえば、ある数値が別の数値より大きいかどうか (演算子が の場合。-gt
他にも多くの演算子があります。 を参照してくださいman test
) をテストします。テストが成功すると (この場合は、the number of parameters
IS が 0 より大きい場合)、成功が返されます。
このshift
コマンドは最初のパラメータを捨てます。また、$#
コード全体は、パラメータを使用して何かを実行し (この場合は画面に表示)、それを破棄し、パラメータがなくなるまでこれを繰り返す、というように見えます。
残っているすべてのパラメータを確認したい場合は、デバッグに役立ち、$@
答え2
$#
==> スクリプトパラメータが渡されました
test
==> 条件評価コマンド
-gt
==> はより大きい
test a -gt b
==> a が b より大きい場合は true、そうでない場合は false
すべてを一緒に入れて:
while test $# -gt 0
==> 渡されるパラメータが増えています(これが変わる理由はシフトによるものです)
物事を複雑にしているのは、shift
while ループの本体内です。
$1
==>は常に最初のパラメータを表します
a
これをより具体的にするために、パラメータ、b
、を渡すとしますc
。
$1
==>はa
最初のパラメータを表します
now を呼び出すとshift
、a
はなくなり、パラメータ リストは now になります。したがって、now を呼び出すとb
、になります。これは、これがリストの最初のパラメータになったためです。もう一度呼び出すと、パラメータ リストは だけになり、したがって、になります。もう一度呼び出すと、パラメータ リストは空のままになるため、while 条件は成功しません (パラメータ リストのサイズが 0 になったため、パラメータ リストは 0 より大きくなくなるため)。これにより、while ループが終了します。c
$1
b
shift
c
$1
c
shift
shift
現在のパラメータを として使用し参照することの利点は何ですか$1
?
これにより、スクリプト内で渡されるパラメータの数を事前に知る必要がなくなり、それに関係なく、while ループ内で現在のパラメータを常に参照してパラメータを 1 つずつ反復処理できるようになります$1
。これは、パラメータ リストの先頭を意味するためです。 をshift
使用すると、最終的にパラメータ リストは空になるため、無限ループに陥らずに終了するには、while 条件を使用して、ゼロより大きいかどうかを確認することが重要です。
答え3
変数の意味を理解するには、以下のスクリプトを実行します。スクリプトを として保存しsomescript.sh
、いくつかの入力パラメータを使用してスクリプトを呼び出します。
#!/bin/bash
echo "I display the total parameters passed to this script from commandline"
echo $#
echo "I display all the parameter values"
echo "Input: $@"
echo "I display the first parameter value"
echo "$1"
shift
echo "After shift: $@"
答え4
回答の再利用を少しお許しいただければ、これが役に立つと思います。
_fn() { set -- "$@" $(cat)
while ${1+:} false ; do
echo "$1" && [ "$1" = "arg2" ] && echo "$1"
$YOUR_CHK
shift
done
}
echo "arg2" | _fn "arg1"
出力
arg1
arg2
arg2
これは、コマンドライン引数との両方を処理しますstdin
。パラメータ配列に少なくとも 1 つの引数が保存されている間のみ、ループを実行しwhile
て引数をチェックします。チェックした引数はすべて破棄されるため、 の一部には、$YOUR_CHK
何らかの形で価値があると思われる情報が保存されているはずです。
_fn
内容がスクリプト本体であったり、シェル関数の形式であったりする場合でも、同じように動作します。
_fn
処理stdin
- この場合は、最初の行で の位置パラメータ シェル配列を、コマンドラインで渡されるすべてのものに代入することによって - または- すべてを経由で出力することによって- 処理"arg2" echo
します。|pipe
set
$@
"$@"
cat
$(comand substitution)
while _fn's $1
最初のパラメータは、ループ条件を満たすために${set+}
シェルの組み込みを置き換えます。 が設定されていない場合、その置き換えは実行されず、条件は と評価され、ループは中断されます。:true
while
$1
false
while
while
ループの各反復において、_fn() echo
esは成功した場合、$1
最初のパラメータ&&
(echo
いつも成功した場合は、文字列が再びesに等しい[ tests ]
かどうかを確認します。$1
"arg2"
&&
[ test ]
_fn() echo
$1
$YOUR_CHK
は null 演算子です。シェルがコードを実行する前に何も評価されない未設定の変数です。
while
ループの各反復ごとに最初のパラメータshift
を削除します$1
。したがって、反復 1 は"$@"
次のようになります。
arg1 arg2
しかし、shift
最初の後は、次のようになります。
arg2
そしてshift
最後に、次のようになります。
これで再び${1+:} false
、$1
が未設定なのでシェルは置換を行わず:true
、代わりにfalse
が評価され、while
ループが終了して終了する。_fn().