スリープ状態のbashスクリプトを起動するにはどうすればよいですか?


27

sleepコマンドを使用して一時停止したプロセスをウェイクアップすることはできますか?


例として、次のスクリプトがあるとします。

#!/bin/bash
echo "I am tired"
sleep 8h
echo "I am fresh :)"

30分後、スクリプトを停止する必要があることがわかりsleep 30mました。つまり、代わりに記述したかったのです。

最後のコマンドは実行されず、疲れたままになるため、呼び出しkill PIDたりCtrl+を押したりすることは望ましくありませんC

プロセスをsleepウェイクアップする方法、またはおそらくウェイクアップをサポートする別のコマンドを使用する方法はありますか?バックグラウンドプロセスとフォアグラウンドプロセスの両方に対するソリューションを歓迎します。


13
本当に大声で叫ぶ。
ドアノブ

2
@Doorknob gawkingは実際には機能しません。前回sleepingプロセスを行ったときpushd、ベッドから離れました。
イマレット

スクリプトに#!行がありません。そして、それはあなたの質問への答え-e#!列にあるかどうかに依存するので重要です。
カスペルド

1
@kasperd完了。好奇心から:-eフラグにはどのような影響がありますか?
-Bittenus

2
デフォルトでは、エラーが発生してもスクリプトは続行します。を使用する#!/bin/bash -eと、エラー後にスクリプトが停止します。単にsleepコマンドを強制終了すると、bashではエラーとして扱われます。それは-eあなたの質問に対する非常に簡単な答えがないことを意味します。-e使用された場合、スリーププロセスを強制終了せずに停止する必要があるため、かなり難しくなります。
カスペルド

回答:


47

Bashスクリプトがを実行しているsleep場合、次のようになりpstreeます。

bash(10102)───sleep(8506)

スクリプトとして実行している場合でも、両方にプロセスID(PID)があります。スリープを中断したい場合は、送信kill 8506してBashセッションを再開します...問題はスクリプト化された環境にあり、sleepコマンドのPIDがわからず、プロセスを確認する人間がいない木。

$$magic変数を使用して、BashセッションのPIDを取得できます。それをどこかに保存できれば、そのPIDのsleep実行されているインスタンスをターゲットにできます。スクリプトに入れたものは次のとおりです。

# write the current session's PID to file
echo $$ >> myscript.pid

# go to sleep for a long time
sleep 1000

そして、そのPIDの下で実行されているインスタンスpkillをnukeに伝えることができますsleep

pkill -P $(<myscript.pid) sleep

繰り返しますが、これはsleep、1つのBashセッションで直接実行されているプロセスのみに限定されます。PIDが正しくログに記録されている限り、これにより、killall sleepまたはpkill sleepに比べてはるかに安全になります。これにより、システム上のプロセスがすべて 無効sleepになります(許可が許可されます)。

3つの個別のbashセッションがあり、2つが実行されている次の例で、この理論を証明できますsleep。左上のbashセッションのPIDを指定しているため、そのセッションのみが強制終了sleepされます。

ここに画像の説明を入力してください


別のアプローチはsleep、バックグラウンドにプッシュし、PIDを保存してからフォアグラウンドに戻すことです。スクリプト内:

sleep 1000 &
echo $! > myscript.sleep.pid
fg

そしてそれを殺すために:

kill $(<myscript.sleep.pid)

5

killなどからの他のシグナルを処理(「トラップ」)するスクリプトを作成して、必要に応じてスクリプトの動作を変更できます。man bashを参照してください:

SIGNALS
   When  bash  is  interactive,  in the absence of any traps, it ignores SIGTERM (so that kill 0 does not
   kill an interactive shell), and SIGINT is caught and handled (so that the wait builtin  is  interrupt-
   ible).   In all cases, bash ignores SIGQUIT.  If job control is in effect, bash ignores SIGTTIN, SIGT-
   TOU, and SIGTSTP.

   Non-builtin commands run by bash have signal handlers set to the values inherited by  the  shell  from
   its  parent.   When  job  control is not in effect, asynchronous commands ignore SIGINT and SIGQUIT in
   addition to these inherited handlers.  Commands run as a result of  command  substitution  ignore  the
   keyboard-generated job control signals SIGTTIN, SIGTTOU, and SIGTSTP.

   The shell exits by default upon receipt of a SIGHUP.  Before exiting, an interactive shell resends the
   SIGHUP to all jobs, running or stopped.  Stopped jobs are sent SIGCONT to ensure that they receive the
   SIGHUP.   To  prevent the shell from sending the signal to a particular job, it should be removed from
   the jobs table with the disown builtin (see SHELL BUILTIN COMMANDS below) or  marked  to  not  receive
   SIGHUP using disown -h.

   If  the huponexit shell option has been set with shopt, bash sends a SIGHUP to all jobs when an inter-
   active login shell exits.

   If bash is waiting for a command to complete and receives a signal for which a trap has been set,  the
   trap  will not be executed until the command completes.  When bash is waiting for an asynchronous com-
   mand via the wait builtin, the reception of a signal for which a trap has been set will cause the wait
   builtin  to  return immediately with an exit status greater than 128, immediately after which the trap
   is executed.

4

スクリプトの次の行に続くスリープを強制終了できます。

pkill sleep

これは、スクリプトだけでなく、システムで実行中のスリーププロセスを強制終了することに注意してください。


1

cron起動時に起動するスリープbashスクリプトがあります。スクリプトは毎分起動し、インターネットから取得した日の出と日の入りに基づいてラップトップのディスプレイの明るさを設定します。ユーザーが設定できる完全な明るさと完全な薄暗さの間の移行フェーズでは、値を3、4、5または毎分計算される値で増減する必要があります。

オリpstreeは彼の答えで簡単に触れましたが、それはすべてのsleepインスタンスを殺すだろうのでそれを拒否しました。これは、pstreeオプションを使用して検索を絞り込むことで回避できます。

使用pstree -hすると、階層全体が表示されます。

$ pstree -h
systemd─┬─ModemManager─┬─{gdbus}
                      └─{gmain}
        ├─NetworkManager─┬─dhclient
                        ├─dnsmasq
                        ├─{gdbus}
                        └─{gmain}
        ├─accounts-daemon─┬─{gdbus}
                         └─{gmain}
        ├─acpid
        ├─agetty
        ├─atd
        ├─avahi-daemon───avahi-daemon
        ├─cgmanager
        ├─colord─┬─{gdbus}
                └─{gmain}
        ├─cron───cron───sh───display-auto-br───sleep
        ├─cups-browsed─┬─{gdbus}
                      └─{gmain}
        ├─dbus-daemon
        ├─fwupd─┬─3*[{GUsbEventThread}]
               ├─{fwupd}
               ├─{gdbus}
               └─{gmain}
        ├─gnome-keyring-d─┬─{gdbus}
                         ├─{gmain}
                         └─{timer}
        ├─irqbalance
        ├─lightdm─┬─Xorg───3*[{Xorg}]
                 ├─lightdm─┬─upstart─┬─at-spi-bus-laun─┬─dbus-daemon
                                                    ├─{dconf worker}
                                                    ├─{gdbus}
                                                    └─{gmain}
                                   ├─at-spi2-registr─┬─{gdbus}
                                                    └─{gmain}
                                   ├─bamfdaemon─┬─{dconf worker}
                                               ├─{gdbus}
                                               └─{gmain}
                                   ├─chrome─┬─2*[cat]
                                           ├─chrome─┬─chrome─┬─2*[chrome─┬─{Chrome_ChildIOT}]
                                                                      ├─5*[{CompositorTileW}]]
                                                                      ├─{Compositor}]
                                                                      ├─{GpuMemoryThread}]
                                                                      ├─{MemoryInfra}]
                                                                      ├─{Renderer::FILE}]
                                                                      ├─{TaskSchedulerRe}]
                                                                      └─{TaskSchedulerSe}]
                                                           ├─7*[chrome─┬─{Chrome_ChildIOT}]
                                                                      ├─5*[{CompositorTileW}]]
                                                                      ├─{Compositor}]
                                                                      ├─{GpuMemoryThread}]
                                                                      ├─{MemoryInfra}]
                                                                      ├─{Renderer::FILE}]
                                                                      ├─{ScriptStreamerT}]
                                                                      ├─{TaskSchedulerRe}]
                                                                      └─{TaskSchedulerSe}]
                                                           ├─chrome─┬─{Chrome_ChildIOT}
                                                                   ├─5*[{CompositorTileW}]
                                                                   ├─{Compositor}
                                                                   ├─{GpuMemoryThread}
                                                                   ├─{Media}
                                                                   ├─{MemoryInfra}
                                                                   ├─{Renderer::FILE}
                                                                   ├─{ScriptStreamerT}
                                                                   ├─{TaskSchedulerRe}
                                                                   └─{TaskSchedulerSe}
                                                           └─2*[chrome─┬─{Chrome_ChildIOT}]
                                                                       ├─5*[{CompositorTileW}]]
                                                                       ├─{Compositor}]
                                                                       ├─{GpuMemoryThread}]
                                                                       ├─{Renderer::FILE}]
                                                                       ├─{ScriptStreamerT}]
                                                                       ├─{TaskSchedulerRe}]
                                                                       └─{TaskSchedulerSe}]
                                                   └─nacl_helper
                                           ├─chrome─┬─chrome
                                                   ├─{Chrome_ChildIOT}
                                                   ├─{MemoryInfra}
                                                   ├─{TaskSchedulerSe}
                                                   └─{Watchdog}
                                           ├─{AudioThread}
                                           ├─{BrowserWatchdog}
                                           ├─{Chrome_CacheThr}
                                           ├─{Chrome_DBThread}
                                           ├─{Chrome_FileThre}
                                           ├─{Chrome_FileUser}
                                           ├─{Chrome_HistoryT}
                                           ├─{Chrome_IOThread}
                                           ├─{Chrome_ProcessL}
                                           ├─{Chrome_SyncThre}
                                           ├─{CompositorTileW}
                                           ├─{CrShutdownDetec}
                                           ├─{D-Bus thread}
                                           ├─{Geolocation}
                                           ├─{IndexedDB}
                                           ├─{LevelDBEnv}
                                           ├─{MemoryInfra}
                                           ├─{NetworkChangeNo}
                                           ├─{Networking Priv}
                                           ├─4*[{TaskSchedulerBa}]
                                           ├─6*[{TaskSchedulerFo}]
                                           ├─{TaskSchedulerSe}
                                           ├─{WorkerPool/3166}
                                           ├─{WorkerPool/5824}
                                           ├─{WorkerPool/5898}
                                           ├─{WorkerPool/6601}
                                           ├─{WorkerPool/6603}
                                           ├─{WorkerPool/7313}
                                           ├─{chrome}
                                           ├─{dconf worker}
                                           ├─{extension_crash}
                                           ├─{gdbus}
                                           ├─{gmain}
                                           ├─{gpu-process_cra}
                                           ├─{inotify_reader}
                                           ├─{renderer_crash_}
                                           ├─{sandbox_ipc_thr}
                                           └─{threaded-ml}
                                   ├─compiz─┬─{dconf worker}
                                           ├─{gdbus}
                                           ├─{gmain}
                                           └─8*[{pool}]
                                   ├─conky───6*[{conky}]
                                   ├─2*[dbus-daemon]

( .... many lines deleted to fit in 30k limit .... )

        ├─vnstatd
        ├─whoopsie─┬─{gdbus}
                  └─{gmain}
        └─wpa_supplicant

ご覧のとおり、一般的なUbuntuログインには多くのPID(プロセスID)が含まれています。

次を使用して、実行中のスクリプトに絞り込むことができます。

$ pstree -g -p | grep display-auto
  |-cron(1198,1198)---cron(1257,1198)---sh(1308,1308)---display-auto-br(1321,1308)---sleep(26552,1308)

私たちは見る:

  • cron シェルを開始しました(プロセスID 1308およびセッションID 1308)
  • シェルは、プロセスID 1321およびセッションID 1308(シェルに一致)で実行されているプログラムを呼び出します
  • 私たちのプログラムはsleepプロセスID 26552で呼び出し、再びセッションID 1308で呼び出します

この時点で使用できpkill -s 1308、シェル、プログラムdisplay-auto-brightnesssleepコマンドを含むセッション全体を強制終了します。代わりにkill 26552、sleepコマンドを強制終了するだけで、プログラムを強制的に起動して明るさを調整します。

表示されるターミナルでこれを手動で入力します。

───────────────────────────────────────────────────────────────────────────────
rick@dell:~$ pstree -g -p | grep display-auto
             |-cron(1198,1198)---cron(1257,1198)---sh(1308,1308)---display-auto-br(1321,1308)---sleep(32362,1308)
───────────────────────────────────────────────────────────────────────────────
rick@dell:~$ sudo kill 32362
───────────────────────────────────────────────────────────────────────────────
rick@dell:~$ pstree -g -p | grep display-auto
             |-cron(1198,1198)---cron(1257,1198)---sh(1308,1308)---display-auto-br(1321,1308)---sleep(1279,1308)
───────────────────────────────────────────────────────────────────────────────
rick@dell:~$ sudo kill 1279
───────────────────────────────────────────────────────────────────────────────
rick@dell:~$ pstree -g -p | grep display-auto
             |-cron(1198,1198)---cron(1257,1198)---sh(1308,1308)---display-auto-br(1321,1308)---sleep(4440,1308)
───────────────────────────────────────────────────────────────────────────────
rick@dell:~$ 

次のステップは、ラップトップがサスペンドから復帰したときに実行します。たとえば、ふたを閉じたとき、それは完全に暗く、画面の明るさは「300」に設定されていました。ふたを開けると昼光になり、明るさを「2000」に設定する必要があります。もちろん、プログラムは1〜59秒で自動的に起動しますが、明るさを即座に設定する方が快適です。

記述した後、サスペンド/レジュームコードを投稿します。うまくいけば今週末。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.