在遠端伺服器上執行本地腳本時擷取主機名和數據
嘗試在遠端主機上執行本地腳本時,無法將遠端伺服器的主機名獲取到本地輸出文件。
例如,我正在執行下面的腳本。
ssh remotehost sh -s < sudo su - ; ./localscript --include Yes > output
以上工作正常。下面是一個範例輸出
script executed data from the remote machine
但我需要這樣的主機名+數據。
remotehost: script executed data from the remote machine
因為我嘗試使用 awk 但它失敗了,有人可以檢查這個並提供幫助。
ssh remotehost sh -s < sudo su - ; ./localscript --include Yes | awk -vhostname=$(hostname) '{print hostname, $0}' > output
這給了我 localhost 主機名。如果我做錯了,請糾正我。
也很抱歉,如果我沒有正確解釋這一點,請發表評論,我會修改並更正它。
我試過這個和它的工作,但無法做“grep”/“awk”輸出
ssh remotehost sh -s < `./localscript --include Yes` ssh remotehost sh -s < `./localscript --include Yes | awk -vhostname=$(hostname) '{print hostname, $0}' > output`
如果要將輸出保存到本地主機上名為“輸出”的文件中:
scp -p ./localscript remotehost: ssh -q remotehost <<'EOF' > output ./localscript --include Yes | awk -vhostname=$(hostname) '{print hostname, $0}' EOF
ssh 選項用於抑制警告消息“
-q
不會分配偽終端,因為標準輸入不是終端”。- 這是必要的,因為標準輸入是從heredoc 重定向的。這使用所謂的“Here Document”或“heredoc”來提供輸入
ssh
。這個詞EOF
只是一個任意詞,本身沒有特殊含義 - 但它通常與 heredocs 一起使用,因為它代表“文件結束”(EOT
也經常用於“文本結束”)。可以使用在要重定向的文本中本身不在一行的任何單詞。從該單詞 (EOF) 之後的下一行到它的下一次出現(單獨一行),所有內容都被視為
ssh
命令的輸入,並在遠端主機上執行。單詞周圍的引號
EOF
使整個heredoc有效地位於單引號字元串中。來自man bash
(搜尋“此處文件”):這裡的文件
這種類型的重定向指示 shell 從目前源讀取輸入,直到看到僅包含分隔符(沒有尾隨空格)的行。然後,所有讀取到該點的行都用作命令的標準輸入(或文件描述符 n,如果指定了 n)。
這里文件的格式是:
[n]<<[-]word here-document delimiter
不會對 word 執行參數和變數擴展、命令替換、算術擴展或路徑名擴展。
如果 word 的任何部分被引用,則分隔符是 word 上引號刪除的結果,並且 here-document 中的行不展開。
如果 word 不被引用,則 here-document 的所有行都經過參數擴展、命令替換和算術擴展,字元序列 <newline 被忽略,並且必須使用 \ 來引用字元、$ 和 `。
如果要將輸出保存到遠端主機上名為 output 的文件中:
scp -p ./localscript remotehost: ssh -q remotehost <<'EOF' ./localscript --include Yes | awk -vhostname=$(hostname) '{print hostname, $0}' > output EOF
注意
> output
重定向在兩個版本中的位置:緊跟在<<'EOF'
第一個版本之後awk
,在第二個版本之後。不過,您似乎真正想做的是重新發明現有工具的一個非常基本的版本,例如Parallel Distributed Shell (pdsh)。
我強烈建議您使用
pdsh
(或幾個類似程序之一)而不是重新發明它。它應該可用於大多數發行版(絕對可用於 debian、ubuntu 等)。例如,在我的家庭網路上,我有四台機器(ganesh、indra、kali 和 hex - 我對最後一台機器的命名方案感到厭煩,並選擇了 Discworld 而不是印度教神)。我已將 pdsh 配置為知道這些主機在“all”組中,因此我可以執行以下內容:
$ pdsh -g all 'uptime; uname -a' hex: 18:35:00 up 45 days, 21:07, 1 user, load average: 0.33, 0.41, 0.43 hex: Linux hex 5.10.0-4-amd64 #1 SMP Debian 5.10.19-1 (2021-03-02) x86_64 GNU/Linux kali: 18:35:00 up 20:40, 2 users, load average: 1.46, 0.92, 0.68 kali: Linux kali 5.10.0-6-amd64 #1 SMP Debian 5.10.28-1 (2021-04-09) x86_64 GNU/Linux ganesh: 18:35:00 up 45 days, 21:23, 22 users, load average: 1.34, 1.67, 1.85 ganesh: Linux ganesh 5.10.0-4-amd64 #1 SMP Debian 5.10.19-1 (2021-03-02) x86_64 GNU/Linux indra: 18:35:00 up 5 days, 19:51, 2 users, load average: 0.00, 0.03, 0.02 indra: Linux indra 5.10.0-6-amd64 #1 SMP Debian 5.10.28-1 (2021-04-09) x86_64 GNU/Linux
請注意,它已經完成了您嘗試對
awk
命令執行的操作 - 在輸出前加上遠端機器的主機名。另請注意:不能保證輸出的順序可以很好地分組。
pdsh
並行執行多個 ssh 連接,遠端機器將需要自己的甜蜜時間來響應。當然,您可以將輸出通過管道傳輸到sort -k1,1
.
pdsh
包括一個pdcp
用於將文件複製到遠端主機的實用程序。例如,如果我想複製./localscript
到我所有的機器並在它們上執行,我會執行:pdcp -p -g all ./localscript '~/' pdsh -g all ./localscript
順便說一句,
pdsh
還附帶了一個很好的實用程序dshbak
,它可以重新格式化輸出,按它來自的主機進行分組。$ pdsh -g all 'uptime; uname -a' | dshbak ---------------- kali ---------------- 18:35:12 up 20:41, 2 users, load average: 1.51, 0.96, 0.70 Linux kali 5.10.0-6-amd64 #1 SMP Debian 5.10.28-1 (2021-04-09) x86_64 GNU/Linux ---------------- indra ---------------- 18:35:12 up 5 days, 19:51, 2 users, load average: 0.00, 0.03, 0.02 Linux indra 5.10.0-6-amd64 #1 SMP Debian 5.10.28-1 (2021-04-09) x86_64 GNU/Linux ---------------- ganesh ---------------- 18:35:12 up 45 days, 21:23, 22 users, load average: 1.52, 1.70, 1.86 Linux ganesh 5.10.0-4-amd64 #1 SMP Debian 5.10.19-1 (2021-03-02) x86_64 GNU/Linux ---------------- hex ---------------- 18:35:12 up 45 days, 21:07, 1 user, load average: 0.26, 0.39, 0.42 Linux hex 5.10.0-4-amd64 #1 SMP Debian 5.10.19-1 (2021-03-02) x86_64 GNU/Linux