Ssh
使用 SSH 遠端同步然後非同步執行
TL; 博士
我想遠端執行一個同步開始的腳本(這樣如果準備命令失敗,本地 ssh 命令會失敗),然後非同步執行,從而終止本地 ssh 命令。
細節
我在遠端伺服器上有一個腳本,可以緩慢下載數 GB 的文件。我想使用 ssh remote-server ’nohup /path/to/script arguments’ 從本地伺服器通過 SSH 啟動此腳本,但是當我知道腳本已成功開始下載時終止 SSH 連接。一旦啟動,SSH 連接就沒有任何用處,在下載過程中系統性地失敗,並阻止本地伺服器上的執行。
我不能這樣做,
ssh -f
或者ssh &
因為如果遠端腳本未啟動、下載前的第一個命令失敗或遠端伺服器無法訪問,我需要命令在本地伺服器伺服器上失敗。我嘗試了各種
nohup
技巧screen
。我得到的最接近的是以下內容:
- 由本地伺服器啟動:
ssh -t me@remote-server 'screen -S long-download /path/to/download.sh'
或者
ssh -t me@remote-server 'nohup screen -S long-download /path/to/download.sh'
- 在
download.sh
遠端伺服器上啟動:preliminary-instructions # if anything fails so far then the local server's ssh command should fail synchronously download-command & some-more-checking screen -d long-download # we can now safely end the ssh session
但不知何故
screen
還是被殺了……樣本複制程式碼
- 在遠端伺服器上,在
/path/to/test.sh
:#!/bin/bash # uncomment this line to validate synchronous failure sleep 10 && echo foo >/tmp/bar & screen -d long-download
- 本地:
ssh -t me@remote-server 'nohup screen -S long-download /path/to/test.sh'
查看 ssh 子系統。我做了類似的事情,但不是使用腳本(即我使用 a.out/elf 編譯的程序。)但我只是使用 bash 腳本進行了測試,它可以工作。
從 ssh 手冊頁:
-s May be used to request invocation of a subsystem on the remote system. Subsystems are a feature of the SSH2 protocol which facilitate the use of SSH as a secure transport for other appli- cations (eg. sftp(1)). The subsystem is specified as the remote command.
在客戶端使用-s(小寫)指定子系統
將另一個子系統條目添加到伺服器上指向您的腳本的 sshd_config。
# override default of no subsystems Subsystem logger /usr/local/libexec/my-logger.sh Subsystem sftp /usr/libexec/sftp-server
您的腳本應該像任何其他具有執行權限的文件一樣啟動。我的例子:
#! /usr/local/bin/bash logger "testing 1.2.3" echo "return text from my-logger" exec 0>&- # close stdin exec 0<&- exec 1>&- # close stdout exec 1<&- exec 2>&- # close stderr exec 2<&- logger "subsystem: nohup new script" nohup /path/to/another/script/logger2.sh & logger "subsystem: the subsystem started script is now done" exit 0
您應該能夠為成功或失敗返回有用的錯誤文本。ssh 連接(以及標準輸入、標準輸出和標準錯誤)一直到子系統結束它為止。子系統可以繼續執行或不執行。
讓您的其他腳本(上面的logger2.sh)休眠5-10 分鐘,這樣您就可以使用netstat 查看ssh 連接消失,ssh 客戶端回到shell,例如ps ax 顯示腳本仍在後台執行。此腳本可能還需要關閉 fd 等。這只是一個簡單的範例。祝你好運。