我在名为 的文本文件中提到了一组服务器network_list.txt
。我如何运行服务器并运行命令并显示结果?我尝试了以下方法:
filename="network_list.txt"
service=httpd
while read -r line
do
name="$line"
ping -c 3 $name > /dev/null 2>&1;
RETVAL=$?
if [ $RETVAL -ne 0 ]
then
echo "$name is down"
else
echo "$name is up and running"
fi
http_status=$(ssh $name ps -ef | grep -v grep | grep $service | wc -l)
if [ $http_status -ne 0 ]
then
echo "$service is up and running in $name"
else
echo "$service is down in $name"
fi
done < "$filename"
但它在第一个服务器之后停止了。
谢谢 :) 。
答案1
您需要将循环中的 SSH 命令的标准输入重定向到任何地方,以防止读取所有行。这应该可以做到:
http_status=$(ssh $name "ps -ef | grep -v grep | grep $service | wc -l" < /dev/null)
答案2
有带-n -x
参数的解决方案:
http_status=$(ssh -nx name ps -ef | grep -v grep | grep $service | wc -l)
禁用-x
X11 转发以删除可能的X11 forwarding request failed
消息。
从 /dev/null重定向-n
stdin(实际上,阻止从 stdin 读取)。
答案3
尽管可以接受的答案完全有效,但我只想提供这个脚本,如果有人遇到它,它可能会有用。
用法
因此,您显然需要更改“Echo $server $serverIP”行下的行以反映您想要使用的实际命令。$1 是您在“./scriptname.sh”之后输入的第一件事 - 例如 ./scriptname.sh $1 $2 $3... - 以下是其分解方式:
$1 应该是包含您的主机名的文件。$2 是您传递给 FunctionC 的位置参数(在此示例脚本中始终会调用它)。$2 和 $3 可用于调用其他函数(A/B)- 或者,如果您始终想运行它们,您可以在 EOF 处用“FunctionA”和“FunctionB”替换 $3 和 $4。
希望这对某人有帮助,这是无价对我来说,在部署包或测试整个域中的东西时。
#! /bin/bash
SVRList=`ls ./$1`
#========[ FUNCTIONS ]===============
FunctionA () {
for server in `cat $SVRList | grep -v ^#` # Makes variable "server" from each line in $SVRlist that is not commented
do
serverIP=$(nslookup $server | tail -2 | awk -F ":" '{print $2}')
echo "============= $server | $serverIP ============="
#command that you'd like to run locally
done
}
FunctionB () {
for server in `cat $SVRList | grep -v ^#`
do
passedvar="192.16.${1}"
serverIP=$(nslookup $server | tail -2 | awk -F ":" '{print $2}')
echo "============= $server | $serverIP ============="
ssh -q $serverIP '#command that you'd like to run remotely'
ssh -q $serverIP '#second command, if you so fancy'
ssh -q $serverIP "ping $passedvar"
#^ is done just to show an example of what can be done
done
}
FunctionC () {
for server in `cat $SVRList | grep -v ^#`
do
passedvar="192.16.${1}"
serverIP=$(nslookup $server | tail -2 | awk -F ":" '{print $2}')
echo "============= $server | $serverIP ============="
ssh -q $serverIP "ping $passedvar"
#^ is done just to show the power of positional parameters.
done
}
#========[ SCRIPT ]==========
if [ $# -lt 2 ]
then
printf "Usage: %s <file containing list of server hostnames> <passed variable> <functions> \n" "$(basename "$0")" >&2
exit 64
else
echo "Starting Script"
fi
FunctionC $2
$3
$4
exit
另外原帖:
为什么要设置 service=httpd?使用 [ 测试和“service=$1”可能更好,其中 $1 可以是 httpd、splunkd 或任何其他服务。此外,变量 http_status 应更改为“service_status”之类的内容,以使脚本更好地记录。
答案4
为什么不使用pssh
?
https://github.com/lilydjwg/pssh
它是一个并行 SSH 工具,内置了从文件获取主机列表的支持:
pssh -h network_list.txt ps -ef | grep -v grep | grep $service | wc -l
然后你就可以按照你喜欢的方式解析输出