私は2台のコンピュータを持っていlocalpc
ますremoteserver
。
localpc
からいくつかのコマンドを実行する必要がありますremoteserver
。必要なことの1つは、数時間実行されるバックアップスクリプトを起動することです。私は、コマンドがlocalpc
「起動」してから最初に存在しなかったかremoteserver
のように、完全に独立して実行されることを望みます。localpc
これまで私がしたことは次のとおりです。
remoteserver
スクリプトを含む:
/root/backup.sh
localpc
これを実行する計画:
ssh root@remoteserver 'nohup /root/backup.sh' &
私がこの仕事をしっかりしているのか?もっと良い方法がありますか?私はこれを行うと問題が発生しますか?
答え1
近いですが、正確ではありません。
どの端末とも独立
ssh root@remoteserver '/root/backup.sh </dev/null >/var/log/root-backup.log 2>&1 &'
リモートプロセスがソケットを開く間はSSHセッションは閉じられないため、SSHソケットに接続されているすべてのファイル記述子を閉じる必要があります。スクリプトの出力に興味がない場合(おそらくスクリプト自体がログファイルの書き込みを担当している可能性がある)にリダイレクトします/dev/null
(ただし、スクリプトを起動できないなどのエラーは隠されます)。
これを使用すると、nohup
ここでは有用な効果はありません。nohup
プログラムの制御端末が消えた場合、実行をスケジュールしたプログラムはHUP信号を受信しませんが、もともと端末がないため、突然プロセスにSIGHUP信号は送信されません。また、nohup
標準出力と標準エラー(標準入力ではありません)がファイルにリダイレクトされますが、端末に接続されている場合にのみそうではありません。
端末から分離
aaron@localpc$ ssh root@remoteserver
root@remoteserver# nohup /root/backup.sh </dev/null &
nohup: appending output to `nohup.out'
[1] 12345
root@remoteserver# exit
aaron@localpc$
nohup
スクリプトを受信しないように制御端末からスクリプトを分離するために使用されます。ため息をつく端末が消えたとき。nohup
また、スクリプトの標準出力と標準エラーを(nohup.out
端末に接続されている場合)というファイルにリダイレクトします。標準入力を直接処理する必要があります。
リモート端末の予約
コマンドをリモート端末で実行し、SSH セッションに接続したくない場合は、端末マルチプレクサで実行します。画面またはマルチプレクサ。
ssh root@remoteserver 'screen -S backup -d -m /root/backup.sh'
screen -S backup -rd
後で、そのシステムで root として呼び出して、スクリプトを実行している端末に再接続できます。
リモートコマンドの自動化
セキュリティを強化するには、直接リモートルートログインを広く開かないでください。秘密鍵ペアを生成し、強制コマンドを発行します。/root/.ssh/authorized_keys
。公開鍵ファイルの内容は、このキーを特定のコマンドの実行にのみ使用できるように指定するカンマ区切りオプションのリストを追加することです。オプションとキーの両方を1行に入力してください。AAAA…== [email protected]
command="…"
command="/root/backup.sh </dev/null >/dev/null 2>/dev/null &",no-port-forwarding,no-agent-forwarding,no-x11-forwarding,no-pty,no-user-rc AAAA…== [email protected]
答え2
screen
真のスタンドアロンコマンドを取得するには、リモートホストで次のものを使用する必要があります。
ssh root@remoteserver screen -d -m ./script
答え3
このスレッドは非常に便利ですが、私の解決策は異なるはずです。
不要な画面プロセスを実行し続けるので、画面ソリューションは気に入らない。リダイレクトとnohupsは次のように使用されます。
ssh root@remoteserver '/root/backup.sh </dev/null >/var/log/root-backup.log 2>&1 &'
ssh コマンドで使用すると動作しません。
リモートシステムで実際のスクリプトを実行するラッパースクリプトを作成しました。ラッパースクリプトはリダイレクトとnohupを設定します。このような:
backupwrapper.sh:
nohup backup.sh > /dev/null 2>&1 &
次に、クライアントコンピュータで実行します(リダイレクトなし)。
# ssh remotemachine "backupwrapper.sh"
#
ssh コマンドが直ちに返され、接続が終了し、スクリプトが実行され続けます。
答え4
〜のようにニールズ、ルートがSSH経由でログインできるようにすることはセキュリティ上の危険です。ログのないシステムでは、実用的なタスクを実行しないことをお勧めします。問題が発生した場合は、トラブルシューティングのメッセージを受け取りたいと思います。これを行う方法を示す他の答えがあります。しかし、私はあなたが求めていることを達成する方法を提案します。それはすべてsh(1)に組み込まれています。 GNU画面は必要ありません(たとえそれが賢い解決策だと思いますが)。次の文字列をコマンドに追加します>&- 2>&- <&- &
。>&-
標準出力終了を示します。2>&-
stderrを閉じることを意味します。<&-
標準入力終了を示します。&
バックグラウンドで実行されることを意味します。
$ ssh myhost 'sleep 30 >&- 2>&- <&- &'
# ssh returns right away, and your sleep job is running remotely
$