Ssh

在 BASH 中使用命名管道控制遠端 ssh 會話

  • January 7, 2020

我的問題主要基於此 https://stackoverflow.com/questions/22479631/pipe-timely-commands-to-ssh?rq=1

我正在關注上述問題,並且能夠連接到伺服器,如下所示:

mkfifo CMDs.txt
exec 7> CMDs.txt

然後從另一個終端我連接到這樣的伺服器:

sshpass -p 'mypass' ssh -tt myuser@${IP} < CMDs.txt 

會話已建立,但它不是互動式會話(應該如此)。但是我可以通過將命令重定向到文件描述符 7 來向遠端伺服器發送命令,例如:

echo "some command" >&7 
echo "some more command" >&7 

這工作正常,並在我啟動會話的另一個終端中顯示輸出。我的目標是發送命令,並在變數中擷取每個命令的輸出,以便我可以在發送另一個命令之前對其進行分析。我認為通過閱讀標準輸出應該是可能的,但我無法弄清楚,因此發布了這個問題。我可以通過將輸出重定向到這樣的文件中來擷取文件中的輸出:

sshpass -p 'mypass' ssh -tt myuser@${IP} < CMDs.txt >>outfile.txt

也如參考問題中所述,exec 7>&-應該終止會話,但它沒有,那麼在我發送所有命令後如何終止會話?

這是一個有趣的(而且非常有用!)。在輸入/輸出重定向領域,有很大的靈活性,因此有多種選擇,但這對我有用。

首先,真正地,使用 ssh-keygen 創建一個私鑰/公鑰對,並將公鑰安裝在遠端伺服器的 authorized_keys 文件中(這很簡單,增強了安全性,網上有很多指南可以做到這一點)。為了獲得額外的信用,密碼保護它,並使用 ssh-agent & ssh-add - 你真的只需要在每次啟動時執行 ssh-agent & ssh-add 一次,然後你就完成了。

無論如何,我像你一樣使用 7 文件描述符,並將我的 FIFO 名稱基於 7,所以我很容易記住我需要重定向到哪個 FD。;)

# fd=7
# server=[whatever_your_server_name_is]
# mkfifo $server.$fd.in $server.$fd.out
# [ssh-agent if needed]
# ssh -tt $server <$server.$fd.in >$server.$fd.out &
# exec 7>$server.$fd.in

現在舞台已經搭建好了。我可以附加一些腳本/過程 $ server. $ fd.out,但在下面的範例中,我只是將 cat 啟動為偵聽器——為了更好的可讀性,我在單獨的 ssh 會話中啟動了它,但如果使用 ‘&’ 作為背景,這並不是絕對必要的:

# cat $server.$fd.out

然後,無論您想要什麼任意命令:

# echo "hostname" >&7
# echo "date" >&7
# echo -e '\003' >&7  # ctrl+c...you're welcome ;)

你會看到輸出。請注意,首先,您將獲得初始登錄 motd/banner/etc,因此您附加到輸出 FIFO 的任何腳本/應用程序都需要能夠處理它。

值得注意的是,單個 FIFO 很可能同時用於讀取和寫入,但 x.input/output 對於我的個人目的效果更好,所以這就是我在這裡展示的內容。

僅供參考:非常感謝“讓我到達那裡”。我一直在試圖弄清楚如何擁有一個“快速”的 ssh RPC,在那裡我建立了一個長時間執行的 ssh 會話,然後可以在以後執行任意命令而無需在每個命令上進行 ssh 身份驗證的成本——我總是將它們串在一起盡可能多的命令來減少成本(甚至發送小腳本來讀取輸出並發出適當的後續命令),但最重要的是,當想要發出快速命令時,ssh 連接和連接總是需要幾秒鐘的成本身份驗證(當然是使用密鑰;)),當想要從多個設備快速獲取某些東西時,那幾秒鐘可能會很痛苦。一些基本的邏輯來處理 ssh 或主機出去吃午飯,並自動重新建立,我

您問題的見解實際上填補了我建構所需內容所需的空白。希望這個答案也能對您有所幫助!:)

引用自:https://serverfault.com/questions/960619