回答:
スクリプトに何かを追加する必要はありません。シェルはそのような機能を可能にします。
T
、停止しています)jobs
端末を入力するか、停止したすべてのジョブを一覧表示します。fg
(フォアグラウンド)」と入力します。ジョブを再開してフォアグラウンドプロセスグループに戻し、ジョブの実行を継続します。例を見る:
root@host:~$ sleep 10 # sleep for 10 seconds
^Z
[1]+ Stopped sleep 10
root@host:~$ jobs # list all stopped jobs
[1]+ Stopped sleep 10
root@host:~$ fg # continue the job
sleep 10
root@host:~$ # job has finished
cmd; cmd; cmd;
は書くことのようなものcmd <newline> cmd <newline> ...
です。あなたが書くことができるスクリプトの代わりに( cmd; cmd; cmd; )
、それはスクリプトのように振る舞います、それによって生成されたサブシェルのせいで(
sleep 10
。3秒後にCTRL + Zを押して数秒後に再開すると、スリープコマンドが7秒未満で終了することに気付きました。これは、あなたが言ったこととは逆です。コマンドは決して停止されないため、バックグラウンドで実行されるだけです。
strace
dのsleep
コマンドを使用してシステムコールがあることが分かりましたnanosleep()
。これは、nanosleep
システムコールの明確な動作のようです。restart_syscall()
既に経過した時間(プロセスがシグナルによって停止された時間を含む)を考慮して適切に調整された時間引数を使用して、中断されたシステムコールを再開します。そのマンページをお読みください:man7.org/linux/man-pages/man2/restart_syscall.2.html
fg %1
またはバックグラウンド(例:)bg %1
。(ジョブが示す数が1つだけ、つまり一時停止されたプロセスが1つだけの[1]+ stopped sleep 10
場合、カオスが示す例:のみ、%n
パーツを省略できます。バックグラウンドプロセスが複数ある場合(実行中または停止中)、必要なプロセスを指定する必要がありますwith:(%n
例: fg %2
%2をフォアグラウンドで再開させるため))
スクリプト内に留まったままスクリプトを一時停止したい場合は、スリープの代わりに読み取りを使用できます。
使用できます
read -t
read -n
スクリプトを続行するために、1文字を読み取るための読み取りのタイムアウトを設定する(事実上任意のキーを押す)
コードを提供していないため、以下はコードの使用例です。
qを押すとread -n1
、キーが押されるまでスクリプトが続行されなくなります。
キーが押されると、チェックがリセットされ、スクリプトは通常どおりループを続行します。
while [[ true ]]; do
read -t2 -n1 check
if [[ $check == "q" ]];then
echo "pressed"
read -n1
check=""
else
echo "not pressed"
fi
echo "Doing Something"
done
またstty -echo
、セクションの先頭とstty echo
末尾に追加して、入力によって画面出力が混乱しないようにすることもできます。
を使用dd
すると、ファイルから1バイトを確実に読み取ることができます。を使用stty
するmin
と、端末の読み取りとtime
出力を10分の1秒で修飾するバイト数を設定できます。これら2つを組み合わせるsleep
と、完全になくても行うことができると思います。ターミナルの読み取りタイムアウトが機能するだけです。
s=$(stty -g </dev/tty)
(while stty raw -echo isig time 20 min 0;test -z "$(
dd bs=1 count=1 2>/dev/null; stty "$s")" || (exec sh)
do echo "$SECONDS:" do your stuff here maybe
echo no sleep necessary, I think
[ "$((i+=1))" -gt 10 ] && exit
done
) </dev/tty
これは、while
私が試してみるために模造した小さなループの例です。2秒ごとdd
に、読み取られたstdin
-リダイレクトされた/dev/tty
-およびwhile
ループループでタイムアウトします。これdd
は、キーを押したためにタイムアウトしないか、または対話型のシェルが呼び出されるためタイムアウトしません。
これがテスト実行です-各行の先頭に出力される数字はシェル変数の値です$SECONDS
:
273315: do your stuff here maybe
no sleep necessary, I think
273317: do your stuff here maybe
no sleep necessary, I think
273319: do your stuff here maybe
no sleep necessary, I think
273321: do your stuff here maybe
no sleep necessary, I think
sh-4.3$ : if you press a key you get an interactive shell
sh-4.3$ : this example loop quits after ten iterations
sh-4.3$ : or if this shell exits with a non-zero exit status
sh-4.3$ : and speaking of which, to do so you just...
sh-4.3$ exit
exit
273385: do your stuff here maybe
no sleep necessary, I think
273387: do your stuff here maybe
no sleep necessary, I think
273389: do your stuff here maybe
no sleep necessary, I think
273391: do your stuff here maybe
no sleep necessary, I think
273393: do your stuff here maybe
no sleep necessary, I think
273395: do your stuff here maybe
no sleep necessary, I think
273397: do your stuff here maybe
no sleep necessary, I think
s=$(stty -g </dev/tty)
ます。電話dd
をかけた直後に、で復元しstty "$s"
ます。最終状態はサブシェルを考慮しないため、これらの設定は親シェルに関係なく保持されます。stty sane
必ずしもあなたがしたいことではありません- sane
その時点での状態であると想定するよりも、状態をあなたが見つけた方法に復元する方が良いです。私がそれを復元していなかったとしたら、それらはあちこちにありecho
ます。私がテストを始めたとき、あなたの答えはここにありませんでした。
sleep 10; notify-send hello
してCTRL + Zを押して停止すると、notify-send hello
実行されます。2番目のコマンドが実行されている場合、どうして最初のプロセスが停止するのですか?タイプがあればその後のfg
2番目のコマンドは、既に実行されているので、私は、明白である、何が起こって見るカント