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
.