Удаленное выполнение программы с помощью запуска xterm с использованием ssh-библиотеки paramiko python

Поток программы:

  1. Подключение к серверу OpenSSH на машине Linux с использованием библиотеки Paramiko
  2. Открыть сеанс X11
  3. Запустить исполняемый файл xterm
  4. Запустите другую программу (например, Firefox), введя имя исполняемого файла в терминал и запустив его.

Я был бы признателен, если кто-нибудь сможет объяснить, как заставить исполняемый файл запускаться в терминале, который был открыт, используя следующий код и предоставить исходный код ( источник ):

import select import sys import paramiko import Xlib.support.connect as xlib_connect import os import socket import subprocess # run xming XmingProc = subprocess.Popen("C:/Program Files (x86)/Xming/Xming.exe :0 -clipboard -multiwindow") ssh_client = paramiko.SSHClient() ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh_client.connect(SSHServerIP, SSHServerPort, username=user, password=pwd) transport = ssh_client.get_transport() channelOppositeEdges = {} local_x11_display = xlib_connect.get_display(os.environ['DISPLAY']) inputSockets = [] def x11_handler(channel, (src_addr, src_port)): local_x11_socket = xlib_connect.get_socket(*local_x11_display[:3]) inputSockets.append(local_x11_socket) inputSockets.append(channel) channelOppositeEdges[local_x11_socket.fileno()] = channel channelOppositeEdges[channel.fileno()] = local_x11_socket transport._queue_incoming_channel(channel) session = transport.open_session() inputSockets.append(session) session.request_x11(handler = x11_handler) session.exec_command('xterm') transport.accept() while not session.exit_status_ready(): readable, writable, exceptional = select.select(inputSockets,[],[]) if len(transport.server_accepts) > 0: transport.accept() for sock in readable: if sock is session: while session.recv_ready(): sys.stdout.write(session.recv(4096)) while session.recv_stderr_ready(): sys.stderr.write(session.recv_stderr(4096)) else: try: data = sock.recv(4096) counterPartSocket = channelOppositeEdges[sock.fileno()] counterPartSocket.sendall(data) except socket.error: inputSockets.remove(sock) inputSockets.remove(counterPartSocket) del channelOppositeEdges[sock.fileno()] del channelOppositeEdges[counterPartSocket.fileno()] sock.close() counterPartSocket.close() print 'Exit status:', session.recv_exit_status() while session.recv_ready(): sys.stdout.write(session.recv(4096)) while session.recv_stderr_ready(): sys.stdout.write(session.recv_stderr(4096)) session.close() XmingProc.terminate() XmingProc.wait() 

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

One Solution collect form web for “Удаленное выполнение программы с помощью запуска xterm с использованием ssh-библиотеки paramiko python”

Ну, это немного взломать, но эй.

То, что вы можете сделать на удаленном конце, следующее: внутри xterm вы запускаете netcat , слушаете любые данные, поступающие на какой-то порт, и делаете все, что попадаете в bash . Это не совсем то же самое, что вводить его в xterm direclty, но это почти так же хорошо, как вводить его в bash напрямую, так что я надеюсь, что это приблизит вас к вашей цели. Если вы действительно хотите напрямую взаимодействовать с xterm, вы можете прочитать это .

Например:

Терминал 1:

 % nc -l 3333 | bash 

терминал 2 (введите echo hi здесь):

 % nc localhost 3333 echo hi 

Теперь вы должны увидеть hi из первого терминала. Теперь попробуйте с помощью xterm& . Это сработало для меня.

Вот как вы можете автоматизировать это в Python. Возможно, вам захочется добавить код, который позволяет серверу сообщать клиенту, когда он готов, вместо использования глупых time.sleep .

 import select import sys import paramiko import Xlib.support.connect as xlib_connect import os import socket import subprocess # for connecting to netcat running remotely from multiprocessing import Process import time # data import getpass SSHServerPort=22 SSHServerIP = "localhost" # get username/password interactively, or use some other method.. user = getpass.getuser() pwd = getpass.getpass("enter pw for '" + user + "': ") NETCAT_PORT = 3333 FIREFOX_CMD="/path/to/firefox &" #FIREFOX_CMD="xclock&"#or this :) def run_stuff_in_xterm(): time.sleep(5) s = socket.socket(socket.AF_INET6 if ":" in SSHServerIP else socket.AF_INET, socket.SOCK_STREAM) s.connect((SSHServerIP, NETCAT_PORT)) s.send("echo \"Hello there! Are you watching?\"\n") s.send(FIREFOX_CMD + "\n") time.sleep(30) s.send("echo bye bye\n") time.sleep(2) s.close() # run xming XmingProc = subprocess.Popen("C:/Program Files (x86)/Xming/Xming.exe :0 -clipboard -multiwindow") ssh_client = paramiko.SSHClient() ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh_client.connect(SSHServerIP, SSHServerPort, username=user, password=pwd) transport = ssh_client.get_transport() channelOppositeEdges = {} local_x11_display = xlib_connect.get_display(os.environ['DISPLAY']) inputSockets = [] def x11_handler(channel, (src_addr, src_port)): local_x11_socket = xlib_connect.get_socket(*local_x11_display[:3]) inputSockets.append(local_x11_socket) inputSockets.append(channel) channelOppositeEdges[local_x11_socket.fileno()] = channel channelOppositeEdges[channel.fileno()] = local_x11_socket transport._queue_incoming_channel(channel) session = transport.open_session() inputSockets.append(session) session.request_x11(handler = x11_handler) session.exec_command("xterm -e \"nc -l 0.0.0.0 %d | /bin/bash\"" % NETCAT_PORT) p = Process(target=run_stuff_in_xterm) transport.accept() p.start() while not session.exit_status_ready(): readable, writable, exceptional = select.select(inputSockets,[],[]) if len(transport.server_accepts) > 0: transport.accept() for sock in readable: if sock is session: while session.recv_ready(): sys.stdout.write(session.recv(4096)) while session.recv_stderr_ready(): sys.stderr.write(session.recv_stderr(4096)) else: try: data = sock.recv(4096) counterPartSocket = channelOppositeEdges[sock.fileno()] counterPartSocket.sendall(data) except socket.error: inputSockets.remove(sock) inputSockets.remove(counterPartSocket) del channelOppositeEdges[sock.fileno()] del channelOppositeEdges[counterPartSocket.fileno()] sock.close() counterPartSocket.close() p.join() print 'Exit status:', session.recv_exit_status() while session.recv_ready(): sys.stdout.write(session.recv(4096)) while session.recv_stderr_ready(): sys.stdout.write(session.recv_stderr(4096)) session.close() XmingProc.terminate() XmingProc.wait() 

Я тестировал это на Mac, поэтому я прокомментировал бит XmingProc и использовал /Applications/Firefox.app/Contents/MacOS/firefox как FIREFOX_CMDxclock ).

Вышеупомянутая не совсем безопасная настройка, так как любой, кто подключается к порту в нужное время, может запускать произвольный код на вашем удаленном сервере, но похоже, что вы планируете использовать его для тестирования в любом случае. Если вы хотите улучшить безопасность, вы можете сделать привязку netcat к 127.0.0.1 а не 0.0.0.0 , настроить туннель ssh (запустите ssh -L3333:localhost:3333 username@remote-host.com чтобы туннелировать весь трафик, полученный локально порт 3333 на remote-host.com:3333), и пусть Python подключится к ("localhost", 3333) .

Теперь вы можете комбинировать это с селеном для автоматизации браузера:

Следуйте инструкциям на этой странице , т. Е. Загрузите файл sarenium standalone server jar, поместите его в /path/to/some/place (на сервере) и pip install -U selenium (опять же, на сервер).

Затем поместите следующий код в selenium-example.py в /path/to/some/place :

 #!/usr/bin/env python from selenium import webdriver from selenium.common.exceptions import NoSuchElementException from selenium.webdriver.common.keys import Keys import time browser = webdriver.Firefox() # Get local session of firefox browser.get("http://www.yahoo.com") # Load page assert "Yahoo" in browser.title elem = browser.find_element_by_name("p") # Find the query box elem.send_keys("seleniumhq" + Keys.RETURN) time.sleep(0.2) # Let the page load, will be added to the API try: browser.find_element_by_xpath("//a[contains(@href,'http://docs.seleniumhq.org')]") except NoSuchElementException: assert 0, "can't find seleniumhq" browser.close() 

и измените команду firefox:

 FIREFOX_CMD="cd /path/to/some/place && python selenium-example.py" 

И посмотрите, как firefox выполняет поиск в Yahoo. Вы также можете увеличить время.

Если вы хотите запускать больше программ, вы можете делать такие вещи до или после запуска firefox:

 # start up xclock, wait for some time to pass, kill it. s.send("xclock&\n") time.sleep(1) s.send("XCLOCK_PID=$!\n") # stash away the process id (into a bash variable) time.sleep(30) s.send("echo \"killing $XCLOCK_PID\"\n") s.send("kill $XCLOCK_PID\n\n") time.sleep(5) 

Если вы хотите выполнить общее управление приложениями X11, я думаю, вам может понадобиться написать похожие «приложения-драйверы», хотя и использовать разные библиотеки. Возможно, вам понадобится поиск «x11 send {mouse | keyboard} events», чтобы найти более общие подходы. Это поднимает эти вопросы , но я уверен, что их намного больше.

Если удаленный конец не отвечает мгновенно, вы можете понюхать свой сетевой трафик в Wireshark и проверить, не загружает ли TCP данные, а не отправляет их по строкам (здесь \n похоже, помогает, но Наверное, нет никакой гарантии). Если это так, вам может быть не повезло , но ничего невозможного . Надеюсь, вам не нужно идти так далеко, хотя 😉

Еще одно замечание: если вам нужно общаться с программами CLI «STDIN / STDOUT», вам может потребоваться сценарий ожидания (например, с помощью pexpect или для простых случаев, когда вы можете использовать subprocess.Popen.communicate] ( http: / /docs.python.org/2/library/subprocess.html#subprocess.Popen.communicate )).

  • Python DBUS SESSION_BUS - зависимость X11
  • Ошибка Kivy - «Не удалось получить окно, прервать»
  • Как «заблокировать клавиатуру», чтобы предотвратить отправку других нажатий на X11 / Linux / Gnome?
  • Как Python может получить доступ к буферу X11?
  • Захват и интерпретация события XI2 RawKeyPress с помощью python
  • Простая программа Linux / X11 для захвата и сохранения фокуса клавиатуры?
  • Как определить приложение, сфокусированное в данный момент?
  • Можно использовать pyplot без DISPLAY?
  • Python - лучший язык программирования в мире.