Чтение вывода программы из stdin вместо использования spawn - PullRequest
0 голосов
/ 30 января 2020

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

Вот функция, которую я имею до сих пор:

ssh_cmd() {
    ssh $USER@$HOST 2>&1 | expect -c "
        log_user 0
        set timeout 5
        expect password: {
            send \"$PASS\n\"
            sleep 2
            log_user 1
        }
    "
}

И затем я хотел бы использовать данный в других местах, чтобы взаимодействовать с процессом s sh следующим образом:

ssh_cmd | expect -c "
    expect '#' {
        send pwd\n
        send exit\n
    }
    expect eof
"

Однако, запустив функцию ssh_cmd с параметром -d для ожидаемого результата, я получаю следующий результат:

expect version 5.45.4

expect: does "" (spawn_id exp0) match glob pattern "password:"? no
ubnt@ui1's password: expect: timed out

Насколько я понимаю, вывод ssh не передается правильно. Я знаю, что обычным способом сделать это было бы использование spawn, но это означало бы, что процесс завершился бы после ожидаемых выходов, и у меня не могло быть обобщенной функции c, которая аутентифицирует сеансы sh и поддерживает процесс жив для дальнейшего использования.

1 Ответ

1 голос
/ 30 января 2020

То, что вы разрабатываете, не сработает. Expect требует запуска процесса из интерпретатора expect с помощью команды spawn. Передача стандартного вывода команды в ожидаемое значение недостаточна.

Вы можете попробовать это:

ssh_cmd() {
    # a default bit of code if user does not provide one.
    # you probably want some checking and emit an error message.
    local user_code=${1:-set timeout 1; send "exit\r"; expect eof}
    expect -c "
        log_user 0
        set timeout 5
        spawn ssh -l $USER $HOST
        expect password: {
            send \"$PASS\n\"
            sleep 2
            log_user 1
        }
        $user_code
    "
}

и затем вызвать его следующим образом:

ssh_cmd '
    expect "#" {
        send pwd\r
        send exit\r
    }
    expect eof
'

Обратите внимание, что одинарные кавычки не имеют особое значение в ожидаемом, это просто обычные символы: вы, вероятно, не хотите, чтобы подсказка представляла собой шаблон из 3 символов ' # '

...