Bashスクリプトでネットワークを待つ

Bashスクリプトでネットワークを待つ

ネットワークブートとネットワーク共有マウントに依存するスクリプトを実行しています。このスクリプトはログイン時に実行されます(起動後に自動的に発生します)。問題は、スクリプトの実行時に通常はまだIPアドレス(DHCP)がないことです。現在、スクリプトを15秒間休止状態にしておきますが、問題が発生した場合はユーザーに通知できるようにしたいので、このアプローチはまったく気に入らません。

私の計画は、まだIPアドレスがない場合を繰り返し、IPアドレスがあれば続けることです。決定的に一定の時間が経過するとタイムアウトが発生するはずです。私が見つけたのは、grepがそれを消費し、それを好きではないif [ ifconfig | grep "192.168.100" ];ということです。そうすれば、bashもどんなgrepを食べたのかを];見つけることができないので怒ります。];もしそうなら、まだタイムアウトを実装していません。

何人かの人々は変数を維持し、各反復ごとにしばらく寝て、毎回変数を増やすことを提案しました。これはうまくいかない完全なスクリプトです(私は初めてbashスクリプトに触れました)。

x=0
while [ ifconfig | grep "192.168.100." > /dev/null ]; do
    echo "no nework"
    if "$x" -gt 200; then
        #Time out here
        exit 1
    x=$((x+1))
    sleep .1
    fi
done

#continue with rest of script...

正しい方向についてのアドバイスをいただきありがとうございます!

ベストアンサー1

シェル構文

シェルスクリプトの条件について混乱しているようです。すべてのシェルコマンドには、0から255の間の整数である終了状態があります。ここで、0 は成功を示し、その他の値は失敗を示します。同様の声明ifそしてwhileブールオペランドはコマンドの終了状態を確認し、0(成功)をtrueとして処理し、他の値(失敗)をfalseとして処理することを期待します。

たとえば、grepコマンドはパターンが見つかった場合は0を返し、パターンが見つからない場合は1を返します。だから

while ifconfig | grep "192.168.100." > /dev/null; do …

192.168.100.の出力でパターンが見つかるたびにループが繰り返されますifconfig。パターン;192.168.100.などの文字列と一致してリテラル文字列を検索するには、オプションをに渡します。条件を変更するには、前に入れてください。192x168 1007.-Fgrep!

while ! ifconfig | grep -F "192.168.100." > /dev/null; do …

スクリプトで変数の値を数値と比較しようとしています。-gt構文の一部である演算子を使用します。条件式次のように理解されるtest注文する。test条件式がtrueの場合、コマンドは0を返し、条件式がfalseの場合は1を返します。

if test "$x" -gt 200; then

通常、[コマンドの代替名がtest使用されます。名前には、コマンドがパラメーターで終わる必要があります]。このコマンドを作成する方法はどちらも同じです。

if [ "$x" -gt 200 ]; then

Bashは、特別な構文を使用してこのコマンドを作成するための3番目の方法も提供します[[ … ]]。この特殊な構文は一般的な解析規則に従う一般的なコマンドですが、シェル構文の一部であるため、通常[よりもいくつかの演算子をサポートできます。[[[ … ]]

もう一度覚えてください[条件式-n-gt、、...などの演算子を含む構文は[「ブール値」を意味しません。すべてのコマンドにブール値があります(終了ステータス= 0?)。

ネットワークが接続されていることを確認してください

ネットワークが動作しているかどうかを検出する方法は信頼できません。具体的には、ネットワークインタフェースが指定された範囲内のIPアドレスを取得するたびにスクリプトがトリガされます。特に、マウントされたネットワーク共有は言うまでもなく、この時点でDNSが起動しない可能性があります。

誰かがログインしたときに実際にこれらのコマンドを実行する必要がありますか?ネットワークが表示されたときにコマンドを自動的に実行する方が簡単です。これを行う方法は、ディストリビューションとNetworkManagerを使用するかどうかによって異なります。

ログインスクリプトの一部としてこれらのコマンドを実行する必要がある場合は、IPアドレスがあるかどうかをテストするのではなく、実際に必要なリソースをテストしてください。たとえば、/net/somenode/somedirマウントされたかどうかをテストするには、次のようにします。

while ! grep -q /net/somenode/somedir </proc/mounts; do
  sleep 1
done

起動またはシステム化されている場合...

それからそれを使うことができます。例えば、ヌーボーリッチと、タスクをstart on net-device-up eth0eth0必要なネットワーク接続を提供するインターフェイス名に置き換えます)としてマークします。 Systemdの使用を参照してください。ネットワークの起動後にスクリプトが実行されるようにしますか?

おすすめ記事