[英]escaping complicated command line arguments in bash and ssh
我正在使用bash腳本來檢索服務器列表的正常運行時間。 它只是從文件中讀取並在服務器上執行遠程命令。 有些服務器可能已啟動很長時間,而有些服務器可能剛剛重啟。 我使用的是非常簡單的方法:
uptime | awk '{print \$2,\$3,\$4}'
如果服務器至少已啟動一天,則此方法有效,但是如果僅啟動了幾個小時,則正常運行時間的輸出將不包括工作日,而僅使用hour:minute格式。
我發現了一些我很喜歡的東西,但是似乎無法在ssh命令中正確地轉義它,更不用說嘗試在bash腳本中傳遞它了:
uptime | awk -F'( |,|:)+' '{d=h=m=0; if ($7=="min") m=$6; else {if ($7~/^day/) {d=$6;h=$8;m=$9} else {h=$6;m=$7}}} {print d+0,"days,",h+0,"hours,",m+0,"minutes."}'
我已經嘗試了幾件事,但是對我來說這應該起作用,並且似乎無法弄清我所缺少的內容:
ssh user@IP "uptime | awk -F'( |,|:)+' '{d=h=m=0; if (\$7==\"min\") m=\$6; else {if (\$7\~\/^day\/) {d=\$6;h=\$8;m=\$9} else {h=\$6;m=\$7}}} {print d+0,\"days,\",h+0,\"hours,\",m+0,\"minutes.\"}'"
我得到的輸出是:
awk: {d=h=m=0; if ($7=="min") m=$6; else {if ($7\~\/^day\/) {d=$6;h=$8;m=$9} else {h=$6;m=$7}}} {print d+0,"days,",h+0,"hours,",m+0,"minutes."}
awk: ^ backslash not last character on line
最后,我嘗試將其放入bash腳本中,如下所示:
while IFS= read -r server; do
ssh -tt user@$server "uptime command" < /dev/null >> /home/user/uptime
done < "$file"
只需將命令發送到ssh的標准輸入即可:
cat <<'EOF' | ssh user@machine
uptime | awk -F'( |,|:)+' '{d=h=m=0; if ($7=="min") m=$6; else {if ($7~/^day/) {d=$6;h=$8;m=$9} else {h=$6;m=$7}}} {print d+0,"days,",h+0,"hours,",m+0,"minutes."}'
EOF
在我看來,您逃避了太多:
ssh user@IP "uptime | awk -F'( |,|:)+' '{d=h=m=0; if (\$7==\"min\") m=\$6; else {if (\$7~/^day/) {d=\$6;h=\$8;m=\$9} else {h=\$6;m=\$7}}} {print d+0,\"days,\",h+0,\"hours,\",m+0,\"minutes.\"}'"
我得到:
6 days, 11 hours, 21 minutes.
更新:
由於同一命令將被發送到多個不同的遠程主機,因此我建議將其保存到一個變量中以方便重用。
command="uptime | awk -F'( |,|:)+' '{d=h=m=0; if (\$7==\"min\") m=\$6; else {if (\$7~/^day/) {d=\$6;h=\$8;m=\$9} else {h=\$6;m=\$7}}} {print d+0,\"days,\",h+0,\"hours,\",m+0,\"minutes.\"}'"
ssh user@IP1 "$command"
ssh user@IP2 "$command"
測試運行:
$ bash script.sh
0 days, 2 hours, 26 minutes.
7 days, 4 hours, 18 minutes.
等待,還有更多:
我經常需要向遠程主機發送多個命令:為此,我發現choroba在他的回答中建議的帶 引號的heredoc語法非常方便。
command=$(cat <<'EOF'
hostname
uptime | awk -F'( |,|:)+' '{d=h=m=0; if ($7=="min") m=$6; else {if ($7~/^day/) {d=$6;h=$8;m=$9} else {h=$6;m=$7}}} {print d+0,"days,",h+0,"hours,",m+0,"minutes."}'
EOF
)
ssh user@IP1 "$command"
ssh user@IP2 "$command"
這是輸出:
$ bash script.sh
server1
0 days, 2 hours, 26 minutes.
server2
7 days, 4 hours, 18 minutes.
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.