特定の要件が満たされるまで、スクリプトの特定の部分を繰り返します。

特定の要件が満たされるまで、スクリプトの特定の部分を繰り返します。

特定の変数が設定されるまでスクリプトの特定の部分を繰り返す方法はありますか?

私の言葉は、私は次のようなものを持っています:

#!/bin/bash

# Check if sudo
if [ $UID -ne 0 ]; then
        echo "You have to run this as sudo" 1>&2
        exit 1
fi

# Get the date for the check
read -p "Please input a date, format 'Jan 12': " chosendate

# Get the time for the check
read -p "Please input the time, format '13:55', leave blank for no time: " chosentime

# Get last results based on input
gotresults=$(last |grep "$chosendate $chosentime" |awk '{print $1" " $5" " $6" " $7" " $9}')

if [[ $(echo "$gotresults"|wc -l) -ne 1 ]]; then
        echo "There are multiple entries corresponding to your input"
        echo
        echo "$gotresults"
        echo
read -p "Please select which entry you desire by typing in the time: " chosentime
        echo "$gotresults" |grep $chosentime
else
        echo "$gotresults"
fi

私はそれを次のように変更したいと思います:

#!/bin/bash

# Check if sudo
if [ $UID -ne 0 ]; then
        echo "You have to run this as sudo" 1>&2
        exit 1
fi

**FLAG1**
# Get the date for the check
read -p "Please input a date, format 'Jan 12': " chosendate

# Get the time for the check
read -p "Please input the time, format '13:55', leave blank for no time: " chosentime

# Get last results based on input
gotresults=$(last |grep "$chosendate $chosentime" |awk '{print $1" " $5" " $6" " $7" " $9}')

if [[ $(echo "$gotresults"|wc -l) -ne 1 ]]; then
        echo "There are multiple entries corresponding to your input"
        echo
        echo "$gotresults"
        echo
        echo "Please select a date/time that only returns one value"
        **GO TO FLAG1**

else
        echo "$gotresults"
fi

これにより、ユーザー入力に応じて1つの値のみが返されるまで、この部分(ユーザー入力を読み取って操作を実行)を繰り返すことができます。

私はこれを「for」ループを使って達成することができると思いますが、そのようなものがあれば簡単になると思います(このシステムは私が使っていたプログラムの中に実装されているようです)。

私が言及したFLAGおよびGO TO FLAGシステムを好む理由は、スクリプト全体でいつでもフラグに戻り、スクリプトフローをよりよく制御できるからです。したがって、FLAG1をどこかに配置し、スクリプトのさまざまな部分(ただ1つではない)からFLAG1に移動できます。これはforループでは実行するのが難しいです。

答え1

質問のスクリプトだけを使用して同様のことを行うことができます(他の潜在的な改善は無視されます)。

 have_results=0
 while [[ $have_results -eq 0 ]]; do
     read -p "Please input a date, format 'Jan 12': " chosendate
     read -p "Please input the time, format '13:55', leave blank for no time: " chosentime

     gotresults=$(last |grep "$chosendate $chosentime" |awk '{print $1" " $5" " $6" " $7" " $9}')

    if [[ $(echo "$gotresults"|wc -l) -ne 1 ]]; then
        echo "Please select a date/time that only returns one value"
    else
        have_results=1
    fi
done

関連情報