セキュリティ上の理由から、通常はオフになっているサーバーがあります。作業したいときは、スイッチを入れてタスクを実行し、再度シャットダウンします。私のタスクは通常15分以内に完了します。 60分後に自動的にシャットダウンするメカニズムを実装したいと思います。
私はcronでこれを行う方法を調査しましたが、サーバーが最後にオンにされたときにcronが考慮に入れていないので、それが適切な方法であるとは思いません。周期的なパターンしか設定できませんが、そのデータは考慮されません。
どうすればこの実装を実行できますか?
毎回同じユーザーとしてタスクを実行する場合は、オプションでオプション-Pを指定してシャットダウンコマンドをプロファイルに追加するだけです。数値は、シャットダウンコマンドが遅延する分数を表します。ユーザーがパスワードなしでSudoを介してシャットダウンコマンドを実行できることを確認してください。
echo "Sudo shutdown -P +60" >> ~/.profile
いくつかのオプションがあります。
shutdown -P
に直接時間を提供してください:
shutdown -P +60
shutdown
man page も指摘することに注意してください:
Time引数を使用すると、システムが停止する5分前に/ run/nologinファイルが作成され、それ以上のログインが許可されないようになります。
at
コマンドを使用します。
systemdユニットファイル または initスクリプト 起動時にshutdown -P 60
を実行します。
起動後にコマンドを実行するには、cronの @reboot
を使用します。
(ルート)crontabに追加:
@reboot shutdown -P +60
最後の2つの方法では、shutdown
に時間引数を使用する代わりにsleep 3600 && shutdown -P now
を使用して、シャットダウンを60分間遅らせることもできます。このようにして、シャットダウンが発行される前の最後までログインできます。
これは XY問題 のように見えます。
私のタスクは通常15分以内で終わります。 60分後に自動的にシャットダウンするメカニズムを実装したいと思います。
60分後にシャットダウンすると、特に複雑な問題が発生し、さらに時間が必要になるというリスクがあります。以前のソリューションの多くは、シャットダウンを遅らせることを容易にしません。
タスクがインタラクティブタスクではなく、代わりに別のマシンから自動的にトリガーされるスクリプトタスクである場合、@ sdkksは すばらしい解決策 を与えました。スクリプトとそのすべてのタスクが終了したらすぐに、マシンにpoweroffを実行するようにタスクを実行する必要があります。
ただし、タスクがインタラクティブタスクである場合は、代わりにアイドル検出を行うことをお勧めします。
GUI(X11)でタスクを実行する場合、ここで説明するアプローチを使用してアイドルGUIセッションを検出できます:システムがアイドル状態で、再びアクティブになったときにコマンドを実行します
端末からタスクを実行する場合は、who
コマンドを使用して、ログインしているユーザーを検出できます。 who
が空の結果を返した場合にマシンをシャットダウンするcronjobを設定できます。これはかなり保守的なアプローチになることに注意してください。コンソールを接続したままアイドル状態にした場合、システムはシャットダウンされません。
もう少しアグレッシブになり、アイドルターミナルセッションも切断したい場合は、以前のアプローチを アイドルSSHセッションの自動切断ClientAliveInterval
およびClientAliveCountMax
と組み合わせることができます。 SSHがなくてもローカルターミナルセッションがある場合の別のアプローチは、w
コマンドで返されるターミナルidle時間を使用することです。
ここでの以前の回答はすべて完璧への要件を満たしていますが、タスクが完了したらすぐにマシンの電源を切ることもできます。
bash
スクリプトはtrap
pedにすることができます。つまり、特定のシグナルを傍受し、必要に応じて特定のタスクを実行できます。 EXIT
は、トラップできる信号の1つです。
次のことができます。
trap
をEXIT
に設定します。これは、自動化タスクの終了を意味します.bashrc
trap
にEXIT
を設定します。つまり、そのマシンからログアウトするたびに、電源を切ります。オプション#1は、タスクがアドホックインスペクションと手動の判断を必要としない限り、理想的なケースです。
オプション#2は、電源をオフにせずに端末を終了するのを忘れた場合をカバーします。ただし、注意点があります。同じマシンへの複数のターミナルが開いていて、そのうちの1つを終了した場合でも、マシンの電源はすべてオフのままです。 (それを回避するためにスクリプト化することができますが、私は解決策を複雑にしません。)
cleanup(){
# Do some tasks before terminating
echo oh la la, cleaning is so Nice
echo "See you later, world"
Sudo poweroff & # finally shutdown
}
trap cleanup EXIT
これは、オプション#2の.bashrc
の最後、オプション#1のスクリプトの上部のどこかにあります。
スクリプトの最後にpoweroff
を使用しないのはなぜですか?
スクリプトの上部にset -eo pipefail
を使用することを好みます。エラーが発生しても、黙って失敗することはありません。それ以上のコマンドの実行を停止します。 trap
of EXIT
信号は、エラーが原因でスクリプトが途中で終了するケースをカバーする必要があります。
ただし、タスクによっては、完了する前にマシンがシャットダウンすることもあります。
スクリプトをデバッグしやすくするために使用するシンプルなbash
テンプレートがあります。多分それはいくつかの役に立つかもしれません。 this Gist を参照してください。
以下は、パラメータを使用してcommand
を実行します。正常に完了すると、ユーザーがpoweroff
を実行できると想定して、ボックスがすぐにオフになります。 Sudo poweroff
を使用する必要がある場合があります。
command --parameters && poweroff
これに対して、次のコマンドは、コマンドが終了するとただちにpoweroff
を実行します。
command --parameters ; poweroff
コマンドの完了後に残り時間が必要だと思われる場合は、次を実行します。
command --parameters ; sleep 3600 ; poweroff
コマンドが残業する可能性があると思われる場合は、1時間に制限できます。
timeout 1h command --parameters ; poweroff
timeout
はcoreutils
パッケージの一部であるため、おそらくすでにお持ちです。
@dirktコメントについて詳しく説明すると、.bashrc
または.profile
、またはログイン時にシェルが使用するファイルにat
コマンドを挿入して、ログインの60分後に自動シャットダウンをスケジュールできます。
何かのようなもの:
at now + 60 minutes -f /sbin/halt
セキュリティについて本当に心配している場合は、電源に機械式コンセントタイマーを使用してください。シャットダウンする時間に設定してください。この方法では、誰もリモートでログインしてシャットダウンを無効にすることはできません。物理的なアクセスが必要になります。
systemd
マシンを使用している場合は、 単調タイマーを使用できます
タイマーユニット/etc/systemd/system/shutdown_after_an_hour.timer
[Unit]
Description=shutdown after an hour
[Timer]
OnBootSec=1h
[Install]
WantedBy=timers.target
タイマーユニット/etc/systemd/system/shutdown_after_an_hour.service
:
[Unit]
Description=shutdown after an hour
[Service]
ExecStart=/sbin/poweroff --force --no-wall
Type=oneshot
それは
# systemctl enable shutdown_after_an_hour.timer
そのステータス(特にシャットダウンまでの残り時間)は、
# systemctl list-timers shutdown_after_an_hour.timer
次回の再起動時に機能しますが、systemctl start
セッションが作成されたときに機能しない(再起動中にトリガーされなかったため)か、1時間経過した場合はすぐにマシンをシャットダウンするため、セッション中に作成されます。実際にどちらが発生するのかはわかりません。その特定のケースをテストしたことはありません。
スクリプト(Sudo shutdown -P 3600
)を/etc/init.d
ディレクトリに配置して、起動時に自動的に実行するようにしてください。
または、anacron
を使用して、/etc/anacrontab
ファイルにコマンドを追加します。また、コマンドの前にNohup
を使用して、ログアウト後もコマンドが機能していることを確認することをお勧めします。
UIDによって開始されるインタラクティブタスクまたは非インタラクティブタスクのサーバーのみが必要な場合は、シャットダウンコマンドを〜/ .bash_logoutファイルに入れることを検討してください。 GNU Bash Manual はこう言っています:
対話型ログインシェルが終了するか、非対話型ログインシェルがexit組み込みコマンドを実行すると、Bashは〜/ .bash_logoutファイル(存在する場合)からコマンドを読み取って実行します。
したがって、「Sudo poweroff」などをログアウトファイルに追加すると、サーバーの電源がオフになりますログアウトするとすぐに現在のセッション、または非インタラクティブなBashセッションがexit
を呼び出したとき。シャットダウンを延期したい場合は、atを使用するか、shutdownに時間遅延を渡すこともできます。
これをよりインタラクティブに行うには、次のバシズムをログアウトファイルに追加します。
# Shutdown unless N or n is pressed within 30 seconds.
shopt -s nocasematch
read -t 30 -N 1 -p 'Shutdown now? (Y/n) '
[[ "$REPLY" =~ n ]] || Sudo poweroff
このソリューションについては、いくつかの注意点があります。
startx
などで起動されなかったX11セッションでは機能しない可能性があります。exit
を呼び出す非インタラクティブなスクリプトがある場合、予期しないシャットダウンが発生する可能性があります。NOPASSWD
を指定していない場合、またはシャットダウンコマンドを実行する前にSudo -v
を呼び出していない場合、sudoersファイルはパスワードを要求する場合があります。つまり、このアプローチが実際のニーズを満たしているかどうか、またはログインしているユーザーの不在を監視するなど、まったく別のアプローチの方が適しているかどうかを検討する必要があります。あなたの走行距離は間違いなく異なります。