Linux

用於遠端收集主機名、IP 和主機總記憶體的 Bash 腳本

  • October 17, 2018

我正在嘗試編寫一個腳本,該腳本將從我輸入腳本的列表中收集遠端主機上安裝的主機名、IP 和總記憶體。該腳本將從 Redhat 和 Solaris 機器收集資訊。下面是我的腳本的樣子:

#!/bin/bash
echo > ip_info.output
echo -e "\n"
for host in `cat ip_adds`
do
echo "Hostname:" $host
sudo ssh -o BatchMode=yes -o ConnectTimeout=5 $host "echo IP Address:; ip route get 1 | awk '{print $NF;exit}'; free -m | grep Mem | awk '{print $1,$2}'"
echo -e "\n"
done

當我執行腳本時,出現以下錯誤:

awk: {print ,}
awk:        ^ syntax error
awk: {print ,}
awk:         ^ syntax error
awk: cmd. line:1: {print ,}
awk: cmd. line:1:          ^ unexpected newline or end of string

我認為問題出在free -m | grep Mem | awk '{print $1,$2}但不知道如何糾正它。如果我free -m | grep Mem | awk '{print $1,$2}直接執行到 shell 我沒有問題。就在劇本里面。

這比它需要的要復雜得多。ssh另外,你為什麼要跑sudo?如果您需要以 root 身份登錄到遠端,那麼您可以這樣做 ( ),但除非您的 ssh 密鑰都屬於 root ,否則您ssh root@$host不太可能需要執行 ssh 。sudo這是一個非常糟糕的主意。

此外,在我的 Arch 系統上,您似乎用來獲取 IP 的命令返回了我使用者的 UID:

$ ip route get 1
1.0.0.0 via 192.168.1.1 dev enp0s31f6 src 192.168.1.111 uid 1000 
   cache 
$ ip route get 1 | awk '{print $NF;exit}'; 
1000

它在我測試的 Ubuntu 上按預期工作:

$ ip route get 1
1.0.0.0 via 123.456.7.8 dev eth0  src 123.456.7.9
$ ip route get 1 | awk '{print $NF;exit}'; 
123.456.7.9

所以也許一個更便攜的版本是在之後列印該欄位src

$ ip route get 1 | sed -nE 's/.* src ([0-9.]+).*/\1/p'
192.168.1.111

您看到的錯誤確實是因為引用。由於您正在執行ssh $host "command",因此雙引號command會導致 shell 擴展在命令中找到的任何變數(例如 awk$2等)。為避免這種情況並將未擴展的符號傳遞給 awk,您需要轉義$.

腳本的更簡單版本:

#!/bin/bash
sshOpts="BatchMode=yes -o ConnectTimeout=5"
echo > ip_info.output
echo ""                
while read host; do
   printf "Hostname:%s" $host
   ssh -o $sshOpts $host "printf 'Hostname: %s\nIP: %s\nMem: %s\n' $host "$(ip route get 1 | sed -nE 's/.* src ([0-9.]+).*/\1/p')" "$(free -m | awk '/Mem/{print $2}')""
done < ip_adds

我已經找到了答案。這與轉義有關,所以我之前添加了 \ $ 1 and $ 2 如下:

free -m | grep Mem | awk '{print \$1,\$2}

引用自:https://unix.stackexchange.com/questions/474996