web-dev-qa-db-ja.com

特定のキーを使用して、長いスリープやその他のものを含むBASHForループを終了します

私はbashスクリプトを持っています

  • forループがあり、これは何度も繰り返され、反復の合間に、場合によっては長時間スリープします。それから

  • 結果をファイルに書き込んでから終了します。

多くのループ反復が完了する前に、必要な結果が得られることがあります。

このような場合、forループからbreakするスクリプトが必要です。

  • 何かをしている、または

  • 睡眠

これまでに収集したデータのレポートファイルを書き込んでいるforループの後、スクリプトの残りの部分を続行するなどの方法で。

Forループからbreakするために、CTRL + Qなどのキーの組み合わせを使用したいと思います。

スクリプトは次のようになります。

#!/bin/bash

for (( c=0; c<=$1; c++ ))
do  

# SOME STUFF HERE
#  data gathering into arrays and other commands here etc

# sleep potentially for a long time
sleep $2

done

#WRITE REPORT OUT TO SCREEN AND FILE HERE
4
Kes

私はこの種のタスクにしばらく触れていませんが、以前はこのように機能していたことを覚えています。

#!/bin/bash

trap break INT

for (( c=0; c<=$1; c++ ))
do  

# SOME STUFF HERE
#  data gathering into arrays and other commands here etc

    echo loop "$c" before sleep

    # sleep potentially for a long time
    sleep "$2"

    echo loop "$c" after sleep

done

#WRITE REPORT OUT TO SCREEN AND FILE HERE

echo outside

アイデアは使用することです Ctrl-C ループを断ち切る。この信号(SIGINT)はトラップによってキャッチされ、ループを中断して残りのスクリプトを追跡します。

例:

$ ./s 3 1
loop 0 before sleep
loop 0 after sleep
loop 1 before sleep
^Coutside

これで何か問題があれば教えてください。

6
user147505

最も簡単な方法は Ctrl+C、これはデフォルトでINTシグナルを提供するため、ほとんどのアプリケーションが停止し、シェルでキャッチできます。

ループ全体を一度に中断するには、サブシェルで実行し、中断されたときにexitを実行します。ここでは、トラップはサブシェルにのみ設定され、それだけが終了します。

#!/bin/bash

(
trap "echo interrupted.; exit 0" INT
while true; do
        echo "running some task..."
        some heavy task 
        echo "running sleep..."
        sleep 5;
        echo "iteration end."
done
)

echo "script end."
5
ilkkachu

場合によっては、「SOME STUFF HERE」を中断せず、シェルスクリプトが待機している間だけ中断するソリューションを用意する方がよい場合があります。

次に、readの代わりに、シェル組み込みコマンドsleepをいくつかのオプションとともに使用できます。

このシェルスクリプトを試してください、

#!/bin/bash

echo "Press 'q' to quit the loop and write the report"
echo "Press 'Enter' to hurry up (skip waiting this time)"

for (( c=0; c<=$1; c++ ))
do  

 echo "SOME STUFF HERE (pretending to work for 5 seconds) ..."
 sleep 5
 echo "Done some stuff"

#  data gathering into arrays and other commands here etc

# sleep potentially for a long time

#sleep $2
 read -n1 -st$2 ans
 if [ "$ans" == "q" ]
 then
  break
 Elif [ "$ans" != "" ]
 then
  read -n1 -st$2 ans
 fi
done

echo "WRITE REPORT OUT TO SCREEN AND FILE HERE"

コマンドhelp readを使用して、readに関する詳細を検索します。

      -n nchars return after reading NCHARS characters rather than waiting
            for a newline, but honor a delimiter if fewer than
            NCHARS characters are read before the delimiter
      -s    do not echo input coming from a terminal
      -t timeout    time out and return failure if a complete line of
            input is not read within TIMEOUT seconds.  The value of the
            TMOUT variable is the default timeout.  TIMEOUT may be a
            fractional number.  If TIMEOUT is 0, read returns
            immediately, without trying to read any data, returning
            success only if input is available on the specified
            file descriptor.  The exit status is greater than 128
            if the timeout is exceeded
2
sudodus