Назад | Перейти на главную страницу

проверка пароля в сценарии bash, вызывающем ожидание

Предыстория: мне нужно скопировать файл с одного сервера на более чем 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:

  • while 1 {}: создает бесконечный цикл. Внутри цикла я определяю различные ожидаемые случаи.
  • log_file fail.txt: создайте файл с именем fail.txt.
  • send_log «текст»: отправляет текст в файл журнала.
  • break: вырывается из бесконечного цикла и завершает ожидаемую секцию.

Если вам нужно управлять сотнями серверов 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