「while」ループは変数の内容を読みません。

「while」ループは変数の内容を読みません。

私の問題を説明するために小さなスクリプトを設定しました。

while同じ時間に繰り返しループを設定しました。$outputNo screen session found

#!/bin/bash

echo Stopping server...

output=$(screen -S tls -X eval 'stuff "stop\015"')

while [ "$output" = "No screen session found." ]
do 
        echo "$output"
        sleep 1
done

echo Server stopped!

このスクリプトを実行するとすぐに停止します。

Stopping server...
Server stopped!

わかりました、だから私の考え$outputNo screen session found.

しかし、ループを次のようなループwhileに切り替えると:until

until [ "$output" = "No screen session found." ]

$output私のループは今見た文字列と同じではないので、ループが繰り返され始めると予想する必要があります。ループが繰り返されている間にecho $output私が追加したコマンドは、ループが実際に終了する必要があることを示します!

Stopping server...
No screen session found.
No screen session found.
No screen session found.
No screen session found.

〜のように$output 同じ No screen session found.

どうしたの?whileanduntilループが内容を無視するのはなぜですか$output

答え1

-xトレースを有効にするスクリプトを実行する場合

bash -x myscript.sh

あなたは見ることができます:

+ echo Stopping server...
Stopping server...
++ screen -S tls -X eval 'stuff "stop\015"'
' output='No screen session found.
' = 'No screen session found.' ']'
+ echo Server 'stopped!'
Server stopped!

ご覧のとおり、@muruのコメントは正しいです。最後にキャリッジリターンがあるため、$output文字列を一致させることはできません。

Bashを使用しているので、簡単な解決策は一致式にワイルドカードを使用することです。

#!/bin/bash

echo Stopping server...

output=$(screen -S tls -X eval 'stuff "stop\015"')

while [[ "$output" = "No screen session found."* ]]
do 
        echo "$output"
        sleep 1
done

echo Server stopped!

このコマンドを実行すると、次のようになります。

Stopping server...
No screen session found.
No screen session found.
.
.
.

@DonHolgoが指摘したように、この時点で無限ループが発生するため、この問題も解決する必要があります。


screenより良い解決策は、出力を一致させようとする代わりに終了コードを調べることです。次のように書くことができます。

#!/bin/bash

echo Stopping server...

while ! screen -S tls -X eval 'stuff "date\015"'; do
  sleep 1
done

echo Server stopped!

screen実行されていない間に起動し、他の端末でセッションを開始すると、次のようになります。

Stopping server...
No screen session found.
No screen session found.
Server stopped!

関連情報