【问题标题】:shell script to run commands over SSH on multiple remote servers [duplicate]在多个远程服务器上通过 SSH 运行命令的 shell 脚本
【发布时间】:2021-09-04 20:15:24
【问题描述】:

我需要检查多个远程服务器上是否正在发生 telnet。

我为多个远程服务器上的 SSH 编写了一个 while 循环,并在 telnet 失败时触发电子邮件。但问题是while 循环仅在第一个服务器上迭代并退出脚本而不读取剩余的服务器。下面是我的shell脚本

#!bin/bash
while read  host_details
do

USERNAME=$(echo $host_details | awk -F"|" '{print $1}')
HOSTIP=$(echo $host_details | awk -F"|" '{print $2}')
PORT=$(echo $host_details | awk -F"|" '{print $3}')
PROXY=$(echo $host_details | awk -F"|" '{print $4}')
PROXY_PORT=$(echo $host_details | awk -F"|" '{print $5}')

STATUS=$(ssh -n  ${USERNAME}@${HOSTIP} -p${PORT} "timeout 4 bash -c \"</dev/tcp/${PROXY}/${PROXY_PORT}\"; echo $?;" < /dev/null)

if [ "$STATUS" -ne 0 ]
then
  echo "Connection to $PROXY on port $PROXY_PORT failed"
  mutt -s "Telnet connection to $PROXY on port $PROXY_PORT failed" abc.def@xyz.com
  
else
  echo "Connection to $PROXY on port $PROXY_PORT succeeded"
  mutt -s "Telnet connection to $PROXY on port $PROXY_PORT succeeded" abc.def@xyz.com
  
fi

done<.hostdetails

我观察到我的脚本仅在我删除 IF 条件并且我的 while 循环按预期遍历所有服务器时才有效。

谁能建议为什么当我使用IF 条件时脚本在第一次迭代后退出?以及如何使其工作并获得电子邮件警报?

【问题讨论】:

  • mutt 可能正在读取文件的其余部分;它真的是为交互式使用而设计的,所以我建议使用不同的邮件程序。另外,我建议使用小写或混合大小写的变量以避免与具有特殊含义的全大写名称发生冲突,并使用while IFS="|" read username hostIP ... 来拆分字段而不是所有那些awk 调用(请参阅BashFAQ #1)。 shellcheck.net会有其他好的建议。
  • mutt 是我在服务器中的唯一选择
  • 然后尝试从 /dev/null 重定向它的输入(就像你对 ssh 所做的那样)。
  • 你是对的,mutt 是这里的罪魁祸首。我只传递“主题”而不是“身体”。因此mutt 在脚本中进入交互模式。现在我已将内容添加到电子邮件“正文”中。它现在运行良好。非常感谢@GordonDavisson
  • 请将解决方案作为答案发布,而不是作为对问题的编辑;这样,您可以将其标记为“已接受”(我认为延迟 48 小时后),并且 stackoverflow 系统将知道问题已解决。见this help entry

标签: linux bash shell ssh


【解决方案1】:

感谢@GordonDavisson 的推荐。

脚本中的mutt 将剩余的服务器详细信息视为输入列表,因此脚本在读取第一个服务器值后终止。

mutt 替换为脚本中的另一个电子邮件程序。 但是,希望使用mutt 的用户,建议将内容添加到他们的电子邮件正文或将标准输入从 mutt 重定向到 /dev/null

以下是可行的解决方案:

#!bin/bash

while IFS="|" read -r userName hostIp Port Proxy proxyPort
do

STATUS=$(ssh -n -tt -o LogLevel=quiet ${userName}@${hostIp} -p${Port} 'timeout 4 /bin/bash -c' \'"</dev/tcp/${Proxy}/${proxyPort}"\'; echo $? < /dev/null | tr -d '\r')
if [ "$STATUS" -ne 0 ]
then
  echo "Connection to $Proxy on port $proxyPort failed" | mutt -s "${hostIp}:Telnet connection to $Proxy on port $proxyPort failed" abc.def@xyz.com
else
  echo "Connection to $Proxy on port $proxyPort succeeded" | mutt -s "${hostIp}:Telnet connection to $Proxy on port $proxyPort succeeded" abc.def@xyz.com
fi
done<.hostdetails

解决方案中的trim命令是删除我在变量中得到的回车符(\r)(STATUS)

【讨论】:

    猜你喜欢
    • 2010-11-03
    • 1970-01-01
    • 2020-10-30
    • 1970-01-01
    • 1970-01-01
    • 2013-11-22
    • 2012-09-23
    • 2016-11-27
    相关资源
    最近更新 更多