將 ssh 和 scp 合併在一個 ssh 會話中

將 ssh 和 scp 合併在一個 ssh 會話中

我有一個如下所示的腳本:

ssh host command1
scp file1 host:/tmp
ssh host command2

有沒有一種方法可以將它們全部合併到一個ssh/scp呼叫中?我遇到的問題是將複製檔案與執行命令結合起來,這必須交錯完成。本來希望有這樣的事情:

ssh_sometool host -c command1 -cp file1 /tmp -c command2

這與語法無關(我可以編寫這樣的函數),而是與同一ssh會話中發生的所有事情有關

答案1

首先,沒有直接或標準的方法可以做你想做的事。另外,讓我澄清一下:沒有辦法用預設的 ssh 用戶端做你想做的事

有一個非常古老的叉子ssh-xfer。請注意,即使該工具的開發人員也強調他們的解決方案是“hackish”並且非常舊,因此您不應該使用它。為與此工具一起使用而修補的最新 SSH 版本是OpenSSH-3.8.1p1(在 Arch Linux 上,目前版本是OpenSSH_7.6p1)。

如果讓事情快速減少主機之間的連接/握手數量對您來說很重要,您可能會考慮某種配置/編排工具。安西布爾似乎是完成任務的最簡單方法,無需太多額外的配置可能是最快的。

無論如何,Ansible 和 Salt 都利用額外的連接來使事情正常工作,我不確定使用它們而不是 ssh/scp 組合是否會在性能方面贏得一些好處。

更新:如果您必須推送和拉取大量文件,並在這些傳輸之間運行一些附加腳本,則幾乎所有配置工具(Chef、Puppet、Salt、Ansible)都會比普通 ssh/scp 更快地完成該操作。

答案2

SSH 允許會話在斷開連線後仍保持一段時間,因此您下次無需啟動連線。以下是 ssh 配置啟用它的選項:

Host *
ControlMaster auto
ControlPath ~/.ssh/sockets/%r@%h-%p
ControlPersist 30

ControlMaster允許透過單一網路連線共享多個會話。當設定為 時auto,每次新嘗試都會檢查相應的連接是否存在並使用它或建立新連接。

ControlPath指定儲存連接的路徑。確保該路徑存在!即建立目錄(插座在這裡,但可以根據需要手動命名)。

ControlPersist指定斷開連線後連線的持續時間。它接受以秒為單位的時間。

若要進一步說明選項,請使用man ssh_config.

將這些新增至您的 後~/.ssh/config,將為這三個命令僅開啟一個會話。

在我的電腦上,它提供了 5 倍的加速:與某些(附近)主機的 100 個連續連接在 30 秒內工作,沒有持久會話,而與它們的連接只需要 5-6 秒。

PS 有時(例如,如果您更改了網路)現有的 ssh 連線會中斷,並且新的連線不會建立,因為有連線的檔案確實存在。在這種情況下,只需手動~/.ssh/sockets刪除必要的文件即可。

答案3

您可以透過 ssh 標準輸入加入並傳遞所有文件,並在遠端會話中接收它們,我的意思是這樣的:

tar -cf - file1 file2 | ssh host 'TDIR=`mktemp -d`; tar -xf - -C "$TDIR"; cat "$TDIR/file1"; command1; command2 ...'


  • cat "$TDIR/file1"命令只是如何存取收到的文件的範例;
  • 在本地和遠端使用 tar 和 -j 或 -J 開關來傳遞壓縮檔案;
  • 您可以將所有命令放入 bash 腳本中,將其包含在存檔中並在遠端執行,例如...tar -xf - -C "$TDIR"; bash "$TDIR/script.sh"'

答案4

在您的腳本中,一旦第一行運行...

ssh host command1

執行將交給 ssh + 您的第二個命令 (scp) 僅在 command1 完成時執行。讓這些並行運行的一種方法是讓每個任務後台運行,就像這樣...

ssh host command1 &
scp file1 host:/tmp &
ssh host command2 &

所以現在所有三個任務都在後台同時運行。

相關內容