У меня есть набор серверов, упомянутых в текстовом файле с именем 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"
Но он останавливается после первого сервера.
Спасибо :) .
Есть решение с -n -x
параметры:
http_status=$(ssh -nx name ps -ef | grep -v grep | grep $service | wc -l)
В -x
отключает пересылку X11, чтобы избавиться от возможных X11 forwarding request failed
Сообщения.
В -n
перенаправляет stdin из / dev / null (фактически предотвращает чтение из stdin).
Вам нужно перенаправить stdin команды SSH в вашем цикле в никуда, чтобы предотвратить чтение всех ваших строк. Это должно сделать это:
http_status=$(ssh $name "ps -ef | grep -v grep | grep $service | wc -l" < /dev/null)
Хотя принятый ответ полностью работает, я хотел бы просто предложить этот сценарий, который может быть полезен, если кто-то с ним столкнется.
использование
Таким образом, вам, очевидно, потребуется изменить строки под строками «Echo $ server $ serverIP», чтобы отразить фактические команды, которые вы хотите использовать. $ 1 - это первое, что вы вводите после "./scriptname.sh", например ./scriptname.sh $ 1 $ 2 $ 3 ... - и вот как это ломается:
$ 1 должен быть файлом с вашими именами хостов. $ 2 - это позиционный параметр, который вы передаете в FunctionC (который всегда вызывается в этом примере скрипта). $ 2 и $ 3 могут использоваться для вызова других функций (A / B) - в качестве альтернативы вы можете заменить $ 3 и $ 4 в EOF на «FunctionA» и «FunctionB», если вы всегда хотите их запускать.
Надеюсь, это кому-то поможет, это было Бесценный мне во время развертывания пакетов или тестирования вещей в домене.
#! /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? Может быть лучше использовать [testing и "service = $ 1", где $ 1 может быть httpd, splunkd или любой другой службой. Кроме того, переменную http_status следует изменить на что-то вроде «service_status», чтобы сценарий лучше документировался.
Почему бы не использовать pssh
?
https://github.com/lilydjwg/pssh
Это параллельный инструмент SSH, в который встроена поддержка получения списка хостов из файла:
pssh -h network_list.txt ps -ef | grep -v grep | grep $service | wc -l
Затем вы можете анализировать вывод, как вам нравится