Refre sh стандартный вывод в paramiko внутри запущенного процесса - PullRequest
2 голосов
/ 19 февраля 2020

Я пытаюсь имитировать c следующее поведение в сценарии Python:
Я выполняю следующую команду на удаленном сервере, используя s sh:

gdb attach `pidof prog`

Затем я получаю следующий экран приветствия в gdb:

Excess command line arguments ignored. (22870)
GNU gdb (GDB) 7.0.1-debian
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
...
0xb7f53c1e in __read_nocancel () at ../sysdeps/unix/syscall-template.S:82
82      ../sysdeps/unix/syscall-template.S: No such file or directory.
        in ../sysdeps/unix/syscall-template.S
(gdb)

нажатие" c "дает следующий вывод:

(gdb) c
Continuing.

Затем, когда я подключаюсь с помощью netcat к серверу через другой порт, я получаю следующий вывод в gdb:

[New process 22898]

Новый идентификатор процесса - это все, что мне нужно, поэтому я хочу автоматизировать process.

У меня есть следующий скрипт Python:

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

s = paramiko.SSHClient()
s.set_missing_host_key_policy(paramiko.AutoAddPolicy())
s.connect(hostname, port, username, password)

stdin, stdout, stderr = s.exec_command("gdb attach `pidof prog`")

stdin.write("c\n") # Pressing C
stdin.flush()

input("Now connect using NC and press Enter")

while not stdout.channel.exit_status_ready():
    time.sleep(1)
    if stdout.channel.recv_ready():
        rl, wl, xl = select.select([stdout.channel], [], [], 0.0)
        if len(rl) > 0:
            data_out = stdout.channel.recv(1024)
            print data_out

Проблема в том, что я получаю тот же вывод, но почему-то не получаю "[Новый процесс *]" , даже когда я подключаюсь, используя n c точно таким же образом.
Более того, только когда я закрываю соединение n c, я вижу выход, но тогда уже слишком поздно, потому что процесс прекратился.
Похоже, что выходной буфер должен быть обновлен в тот момент, что он, кажется, не делает г

1 Ответ

0 голосов
/ 25 февраля 2020

У меня были похожие проблемы с использованием stdin после команды и захвата stdout, и я исправил его, используя опцию "get_pty = True".

stdin, stdout, stderr = s.exec_command("gdb attach `pidof prog`",get_pty=True)

В документации Paramiko говорится, что при использовании опции get_pty = True открывается выделенный псевдо-терминал, и в той же документации предлагается использовать get_pty = True, если вы собираетесь используйте больше команд / взаимодействуйте с ним:

get_pty (* args, ** kwds):

Запрос псевдотерминала с сервера. Это обычно используется сразу после создания клиентского канала, чтобы попросить сервер предоставить некоторую базовую семантику терминала c для оболочки, вызываемой с помощью invoke_shell. Нет необходимости (или нежелательно) вызывать этот метод, если вы собираетесь выполнить одну команду с exec_command.

Также, если вы используете get_pty = True Вы сможете выполнять больше команд над одной и той же оболочкой. Следовательно, будет возможно выполнить history | grep [SOME REGEX], как предложено SunPaz .

...