Предыстория: мне нужно скопировать файл с одного сервера на более чем 100 серверов в тестовой среде. после копирования файла требуется, чтобы права доступа к файлу были изменены / проверены. Это все серверы Linux. у большинства из них один и тот же пароль для входа в систему, но у некоторых может и не быть.
Мне нужна помощь с созданием цикла в моем сценарии bash. На самом деле это вызов Expect. Область, в которой я хочу "улучшить" или исправить, - это несколько вещей.
Я попытался написать часть пароля, думая, что это цикл, но я не совсем уверен, подходит ли этот метод мышления. Я попытался просто добавить еще один «ожидаемый пароль:», думая, что если он получит приглашение во второй раз, нужно выйти, но мне было трудно заставить это работать. Спасибо!
#!/bin/bash
while read ip; do
sleep 2
expect <<- DONE
set timeout 1
spawn scp yoman.txt root@$ip:/felixtemp
if above command fails, dump the IP to fail.txt, otherwise continue
expect yes/no { send yes\r }
expect Password: { send aaaaaa\r } #if this is good, continue the script from *****
else #exit the script
expect Password: { send 033\r }
expect # { send "echo 'password failed'\r" }
&& dump to a text file called fail.txt
***** expect # { send "exit\r\r" }
sleep 1
set timeout 1
spawn ssh root@$ip
sleep 2
expect yes/no { send yes\r }
sleep 2
expect Password: { send aaaaaa\r }
sleep 5
expect # { send "cd /felixtemp\r" }
expect # { send "chown informix:informix yoman.txt\r" }
expect # { send "chmod 775 yoman.txt\r" }
expect # { send "sum yoman.txt | grep 10350 && echo 'transfer good' || echo 'transfer bad'\r" }
expect # { send exit\r }
sleep 1
DONE
done < ip.txt
Ни один из предыдущих комментариев не ожидал внутри сценария bash, как запросил OP.
Недавно мне нужно было выполнить аналогичную задачу, поэтому вот мое решение с использованием expect:
expect <<- DONE
set timeout 1
spawn scp yoman.txt root@${ip}:/felixtemp
while 1 {
expect {
"no)?" {
send "yes\n"
}
"denied" {
log_file fail.txt
send_log "Couldn't log in to ${ip}.\n";
exit 1
}
"assword:" {
send "${password}\n"
}
"100%" {
break;
}
}
}
expect eof
DONE
Объяснение синтаксиса expect:
Если вам нужно управлять сотнями серверов Linux, вы должны использовать инструмент управления конфигурацией для выполнения этих задач. Доступен очень простой инструмент управления конфигурацией, единственное требование для управляемой системы - python 2.4 или более ( http://docs.ansible.com/intro_installation.html#managed-node-requirements ).
Ваша проблема решена с помощью ansible:
1) Определите список хостов, вы можете определить пароль по умолчанию для всех хостов и другой пароль для некоторых хостов.
[hosts_list]
172.17.0.101 ansible_ssh_user=root ansible_ssh_pass=password
172.17.0.102 ansible_ssh_user=root ansible_ssh_pass=oldpassword
172.17.0.103
172.17.0.104
[hosts_list:vars]
ansible_ssh_user=root ansible_ssh_pass=default_password
2) Определите простую книгу воспроизведения, содержащую те задачи, которые вы хотите выполнить на управляемых узлах.
root@node1:~# cat play.yoman
---
- hosts: hosts_list
tasks:
- name: "Build hosts file"
copy: src=/root/yoman.txt dest=/tmp/felixtemp owner=user group=adm mode=0755
3) Запустите playbook и проверьте результат
root@node1:~# ansible-playbook -i hosts_list play.yoman
PLAY [hosts_list] *************************************************************
GATHERING FACTS ***************************************************************
fatal: [172.17.0.104] => SSH encountered an unknown error during the connection. We recommend you re-run the command using -vvvv, which will enable SSH debugging output to help diagnose the issue
fatal: [172.17.0.103] => SSH encountered an unknown error during the connection. We recommend you re-run the command using -vvvv, which will enable SSH debugging output to help diagnose the issue
ok: [172.17.0.101]
fatal: [172.17.0.102] => Authentication failure.
TASK: [Build hosts file] ******************************************************
ok: [172.17.0.101]
PLAY RECAP ********************************************************************
to retry, use: --limit @/root/play.yoman.retry
172.17.0.101 : ok=2 changed=0 unreachable=0 failed=0
172.17.0.102 : ok=0 changed=0 unreachable=1 failed=0
172.17.0.103 : ok=0 changed=0 unreachable=1 failed=0
172.17.0.104 : ok=0 changed=0 unreachable=1 failed=0
Вы получаете список серверов, на которых выполняется задача, и список серверов, на которых задача не выполняется, с указанием причин (недоступный сервер или неправильный пароль). Вы также получаете подмножество сервера, на котором файл, его разрешение и содержимое не были изменены, потому что они уже обновлены.
Почему бы тебе не использовать sshpass
?
Петля со столом:
tab=(
1.2.3.4
4.3.2.1
...
);
for (( i = 1; i < ${#tab[*]}; i++ )) {
echo ${tab[i]};
...
}
Для установки правильного пароля вам потребуются некоторые условия для определенных IP-адресов.
SCP
sshpass -p $PASSWORD scp -o StrictHostKeyChecking=no $FILE $USER@$HOST:$PATH
Согласно справочной странице, возвращаемые значения:
0 Успех
1 Неверный аргумент командной строки
2 Приведены противоречивые аргументы
3 Общая ошибка времени выполнения
4 Нераспознанный ответ от ssh (ошибка синтаксического анализа)
5 Неверный / неверный пароль
6 Открытый ключ хоста неизвестен. sshpass завершает работу без подтверждения нового ключа.
Полезно, если вы хотите вывести $ HOST в файл с возвращаемым значением:
sshpass -p $PASSWORD scp -o StrictHostKeyChecking=no $FILE $USER@$HOST:$PATH
if [ $? -ne 0 ]
then
echo $HOST:$? >> file.txt;
fi
SSH
Для отправки команд:
sshpass -p $PASSWORD ssh -o StrictHostKeyChecking=no $USER@$HOST $CMD