Ожидать сценарий с необязательной парольной фразой ssh-agent?

Я хочу автоматизировать резервное копирование базы данных с помощью ожидаемого: во-первых, сценарий устанавливает перенаправленный порт с порта удаленной базы данных на мой локальный компьютер с помощью ssh. Затем я использую утилиту базы данных, чтобы сбросить все базы данных.

Поэтому внутри bash- скрипта есть следующий ожидаемый скрипт:

#!/bin/sh

expect <<- DONE
  set timeout -1

  # port-forward remote database port 3306 to local port 3307
  spawn ssh -M -S /var/run/examplecom-mysql-socket -fnNT -L 3307:localhost:3306 someuser@example.com

  expect {
    # conditional prompt appears in case ssh-agent is not active
    "*.ssh/id_rsa':*" {
      send -- "$SSH_PASSPHRASE\r"
    }
    # ?!?!?!? What to expect here in case ssh-agent is active, therefore no password needed, and therefore no prompt appears?
  }

  # dump remote database by connecting to forwarded port
  spawn mysqldump --all-databases --user=root --password --protocol=TCP --host=localhost --port=3307 --verbose --result-file=${DB_DUMP_FILE}

  expect {
    # prompt appears for database password 
    "*?asswor?:*" {
    send -- "$PASSWORD_MYSQL_ROOT\r"      
    }
  }

  expect eof
DONE

Этот сценарий может выполняться в двух сценариях:

  • Либо ssh-agent в данный момент не активен. В этом случае порожденный процесс SSH предложит Enter passphrase for key '${HOME}/.ssh/id_rsa':, которому первое правило ожидания успешно соответствует, и правильно отправляет SSH-фразу.
  • Или ssh-agent в данный момент активен. В этом случае порожденный процесс ssh молча устанавливает переадресацию портов и не требует или не запрашивает пароль SSH.

Я изо всех сил пытаюсь заставить оба сценария работать в моем ожидаемом сценарии. В частности, я не знаю, как изменить сценарий так, чтобы "молчащий" активный-ssh-agent был "ожидаемым", и поэтому ожидаемый сценарий мог продолжить запускать дамп базы данных.

Я пытался ожидать многоплановый подход (выше ?!?!?!? местоположение комментария), попробовав:

  • ожидая перевода строки,
  • ожидая моего приглашения оболочки,
  • ожидая eof,

Но никто не работал. Я нашел похожие проблемы и предложил решения вокруг StackExchange: * Как использовать ожидаемый с необязательными подсказками? * https://superuser.com/q/412259/137881 * TCL / Expect Scripting - использование условного оператора для попытки ввода вторичного пароля для входа

Но solutinos, кажется, вызывают дублирование кода: каждое условное приглашение означает копирование и вставку остальной части сценария, что заставляет сценарий быстро извиваться с вложенными условными запросами для каждого оператора ssh.

Как можно ожидать корректной работы в ситуациях, когда ssh не запрашивает пароль / пароль из-за активного ssh-agent?

1 ответ

Решение

Да, это смешно. Так как вы используете SSH -N, вы не запускаете никакой процесс на удаленном хосте, а сессия ssh просто сидит там. Вам просто нужно поспать пару секунд и надеяться, что туннель будет установлен.

set timeout 2
spawn ssh -M -S /var/run/examplecom-mysql-socket -fnNT -L 3307:localhost:3306 someuser@example.com

expect {
    # conditional prompt appears in case ssh-agent is not active
    "*.ssh/id_rsa':*" { send -- "$SSH_PASSPHRASE\r" }
    # wait until the timeout, then carry on with the rest of the script
    timeout
}

set timeout -1
# ...

Или удалить -N, тогда вы можете ожидать увидеть приглашение на удаленном хосте.

spawn ssh -M -S /var/run/examplecom-mysql-socket -fnT -L 3307:localhost:3306 someuser@example.com
# ..........................................^^^^

expect {
    # conditional prompt appears in case ssh-agent is not active
    "*.ssh/id_rsa':*" { send -- "$SSH_PASSPHRASE\r" }
    # I assume your prompt ends with a dollar sign and a space
    -re {\$ $}
}

Теперь вы можете создавать команду mysql и взаимодействовать с ней.

Другие вопросы по тегам