
Мне нужно создать скрипт, который будет входить на все серверы, перечисленные в servers.txt
. Я хочу использовать пароль, а не беспарольный. После входа в систему мне нужно задать переменную и выполнить if
- then
- else
. После завершения работы он должен создать файл на локальной машине, а не на удаленной. (Локальный) файл будет содержать имя хоста(ов) машин, на которых не был запущен определенный процесс.
Общая идея такова:
#!/bin/bash
while read line
do
sshpass -p ******** ssh "mydomain1\admin1"@$line bash -s << EOF
pwd=*********
var=$"(ps -ef | grep http | grep -v grep | wc -l)"
if (( var > 0 ))
then
echo "$pwd" | sudo -S ps -ef | grep patrol | grep -v grep | awk '{print $2}' | xargs kill
echo "$pwd" | sudo -S rm -rf /data/abc /etc/efg
#need to create the log on local machine, not on remote machine
hostname >> /find.txt
else
#need to create the log on local machine, not on the remote machine
hostname >> /agentnotthere.txt
fi
EOF
#servers.txt contains server names
done < servers.txt
Очевидно, что строки 5-16 вышеприведенного кода образуют документ here, содержащий команды для запуска на удаленном хосте. В этом документе here у меня есть команды hostname >> /find.txt
и hostname >> /agentnotthere.txt
. Как указано в моем вводном абзаце и снова в комментариях в коде, я хочу, чтобы (удалённое) имя хоста было записано в локальный файл, а не в файл на удалённой машине. Очевидно, что команда на удалённой машине запишет в файлcommand >> filename
на удаленной машине.
Как мне заставить мой скрипт, который выполняет ssh
несколько команд на удаленной машине(ах), записывать вывод в локальный файл на основе результатов тестов, выполненных на удаленной машине(ах)?
решение1
Я не думаю, что есть простой способ сделать то, что вы хотели, то есть записать отдельные файлы на локальном хосте из скрипта, который выполняется на удаленной машине.
Однако вы можете легко направить вывод скрипта в один локальный файл:
ssh host << EOF > output_file
some commands
to be executed
EOF
При этом вы можете реструктурировать скрипт так, чтобы он выполнялся ssh
несколько раз (это увеличит ssh
накладные расходы, но вы можете уменьшить большую их часть, используя ControlPersist
в ssh
файле конфигурации).
Так что вместо этого вы получите что-то вроде этого (псевдо-bash):
echo "get the output of var script" | ssh host > var_value
if var read from the file is more than zero; then
echo "the thing you want" | ssh host >> /find.txt
else
echo "the other thing you want" | ssh host >> /agentnotthere.txt
fi
Это должно отлично подойти для вашего варианта использования :)
Мои два цента по поводу самого сценария:
- Ansible или один из других инструментов управления конфигурацией, вероятно, лучше подойдет для этой задачи, чем написание bash-скриптов.
- Использование паролей SSH вместо аутентификации по ключу плохо с точки зрения безопасности. Но я был в ситуациях, когда это было невозможно реализовать из-за политики компании/старых встроенных вещей, которые не поддерживают это/и т. д.
- Вместо использования старого
ps aux | grep -v grep | grep something
шаблона вы можете использоватьpgrep
иpkill
. Они входят в стандартcoreutils
, поэтому, если вы не используете действительно устаревшие системы, они должны быть доступны на них.