「while test $# -gt 0」は何をしますか?

「while test $# -gt 0」は何をしますか?

関数を作成しようとしており、うまく動作する例を見つけたと思いますが、その背後にあるロジックをすべて理解しているわけではありません。

もっと具体的に言うと、「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 parametersIS が 0 より大きい場合)、成功が返されます。

このshiftコマンドは最初のパラメータを捨てます。また、$#

コード全体は、パラメータを使用して何かを実行し (この場合は画面に表示)、それを破棄し、パラメータがなくなるまでこれを繰り返す、というように見えます。

残っているすべてのパラメータを確認したい場合は、デバッグに役立ち、$@

答え2

$#==> スクリプトパラメータが渡されました

test==> 条件評価コマンド

-gt==> はより大きい

test a -gt b==> a が b より大きい場合は true、そうでない場合は false

すべてを一緒に入れて:

while test $# -gt 0==> 渡されるパラメータが増えています(これが変わる理由はシフトによるものです)

物事を複雑にしているのは、shiftwhile ループの本体内です。

$1==>は常に最初のパラメータを表します

aこれをより具体的にするために、パラメータ、b、を渡すとしますc

$1==>はa最初のパラメータを表します

now を呼び出すとshiftaはなくなり、パラメータ リストは now になります。したがって、now を呼び出すとb、になります。これは、これがリストの最初のパラメータになったためです。もう一度呼び出すと、パラメータ リストは だけになり、したがって、になります。もう一度呼び出すと、パラメータ リストは空のままになるため、while 条件は成功しません (パラメータ リストのサイズが 0 になったため、パラメータ リストは 0 より大きくなくなるため)。これにより、while ループが終了します。c$1bshiftc$1cshift

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します。|pipeset$@"$@"cat$(comand substitution)

while _fn's $1最初のパラメータは、ループ条件を満たすために${set+}シェルの組み込みを置き換えます。 が設定されていない場合、その置き換えは実行されず、条件は と評価され、ループは中断されます。:truewhile$1falsewhile

whileループの各反復において、_fn() echoesは成功した場合、$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().

関連情報