Python посылает управление + Q, затем управляет + A (специальные клавиши)

Мне нужно отправить некоторые специальные нажатия клавиш и не знаю, как это сделать.

Мне нужно отправить Ctrl + Q, а затем Ctrl + A на терминал (я использую Paramiko).

Я пробовал

shell = client.invoke_shell()

shell.send(chr(10))
time.sleep(5)
shell.send(chr(13))

shell.send('\x11')
shell.send('\x01')

print 'i tried'

Я вижу, что два возврата успешно завершаются, но потом ничего, он не выходит из picocom (также отметить, что у меня неправильный путь, ожидая ctrl + a, затем ctrl + q)

если это помогает этому устройству http://www.cisco.com/c/en/us/td/docs/routers/access/interfaces/eesm/software/configuration/guide/4451_config.html#pgfId-1069760

как вы можете видеть на шаге 2

Step 2 Exit the session from the switch, press Ctrl-a and Ctrl-q from your keyboard:

Switch# <type ^a^q>
Thanks for using picocom
Router#

UPDATE:

Я попробовал \x01\x16\x11\n, но это возвращает

Switch#
Switch#
*** baud: 9600
*** flow: none
*** parity: none
*** databits: 8
*** dtr: down

Switch#

похоже, что это может быть другая специальная команда?

Ответы

Ответ 1

Это отлично работает для меня, возвращаясь точно, чего я ожидаю. Очевидно, что некоторые фрагменты отсутствуют в вашем коде выше, поэтому для этого требуется небольшое крыло.

import sys
import time
import getpass
import paramiko

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('127.0.0.1',
            username='apsuser',
            password=getpass.getpass('Password: '))
shell = ssh.invoke_shell()
shell.settimeout(0.25)

shell.send('picocom /dev/ttyS0\n')
time.sleep(2)
sys.stdout.buffer.write(shell.recv(10000))
sys.stdout.buffer.flush()

shell.send('\x01')
shell.send('\x11')

time.sleep(2)
sys.stdout.buffer.write(shell.recv(10000))
sys.stdout.buffer.flush()
print()
time.sleep(2)

И результаты:

Password: 

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Thu Apr 14 19:55:57 2016 from 127.0.0.1
picocom /dev/ttyS0
[email protected]:~$ picocom /dev/ttyS0
picocom v1.7

port is        : /dev/ttyS0
flowcontrol    : none
baudrate is    : 9600
parity is      : none
databits are   : 8
escape is      : C-a
local echo is  : no
noinit is      : no
noreset is     : no
nolock is      : no
send_cmd is    : sz -vv
receive_cmd is : rz -vv
imap is        : 
omap is        : 
emap is        : crcrlf,delbs,

Terminal ready

Thanks for using picocom
[email protected]:~$ 

Итак, что я сделал, что ваш код не делает?

Ответ 2

Так же, как предположение: возможно, псевдотерминал поможет

import paramiko
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(...)
channel = сlient.get_transport().open_session()
channel.get_pty()
channel.settimeout(5)
channel.exec_command('\x11\x01') 

Ответ 3

Нажатие клавиши Ctrl + на самом деле является "удобным" способом ввода управляющих символов ASCII. Это делается путем вычитания 64 из кода ASCII введенного ключа (с использованием заглавной буквы, где это применимо). Комбинация Ctrl + H, например, эквивалентна вводу пробела (H имеет код 72, 72-64=8, символ пробела). На этой странице Википедии перечислены управляющие символы ASCII, связанные с их комбинациями клавиш, поэтому Ctrl + A, Ctrl + Q эквивалентны отправке строки "\x01\x11" через канал paramiko:

channel = client.invoke_shell()
channel.send('\x01\x11')

Обновить

Чтобы проверить, что в действительности передается при нажатии Ctrl + A Ctrl + Q, я разработал небольшую тестовую программу:

# decode.py
import sys

while True:
    inp = sys.stdin.read(1)
    if len(inp) == 0:
        break
    print ord(inp[0])

Если я сейчас позвоню через ssh localhost python decode.py и ssh localhost python decode.py Ctrl + A Ctrl + V Ctrl + Q (я должен сделать Ctrl + V, потому что [ TG20] + Q интерпретируется как XON моей локальной оболочкой и не передается на другую сторону), затем Enter Ctrl + D, чтобы закрыть соединение, я получаю 1, 17 и 10 как ординалы, или '\x01\x11\n', как и ожидалось.

Я в основном получаю то же самое, выполняя printf '\x01\x11\n' | ssh localhost python decode.py printf '\x01\x11\n' | ssh localhost python decode.py. Однако, если я выделю pty на удаленном конце через printf '\x01\x11\n' | ssh -tt localhost python decode.py printf '\x01\x11\n' | ssh -tt localhost python decode.py \x11 перехватывается удаленным pty и не передается в работающий скрипт (я получаю 1, 10 качестве вывода). В этом случае полезно отправить Ctrl + V (\x16) перед Ctrl + Q, который инструктирует pty передать следующий символ V erbatim. Как и ожидалось printf '\x01\x16\x11\n' | ssh -tt localhost python decode.py printf '\x01\x16\x11\n' | ssh -tt localhost python decode.py выводит 1, 17 и 10.