使用paramikopythonsh库通过xterm运行远程执行程序
该计划的流程如下:使用paramikopythonsh库通过xterm运行远程执行程序,python,multithreading,ssh,x11,paramiko,Python,Multithreading,Ssh,X11,Paramiko,该计划的流程如下: 使用Paramiko库连接到Linux机器上的OpenSSH服务器 打开X11会话 运行xterm可执行文件 通过在终端中键入可执行文件名并运行它来运行其他程序(如Firefox) 如果有人能解释如何使用以下代码在终端中运行某个可执行文件,并提供示例源代码(),我将不胜感激: 我正在考虑在子线程中运行程序,而运行xterm的线程正在等待子线程终止。嗯,这有点像黑客,但是嘿 您可以在远程端执行以下操作:在xterm内部,运行netcat,监听从某个端口传入的任何数据,并将任何数
我正在考虑在子线程中运行程序,而运行xterm的线程正在等待子线程终止。嗯,这有点像黑客,但是嘿 您可以在远程端执行以下操作:在xterm内部,运行
netcat
,监听从某个端口传入的任何数据,并将任何数据导入bash
。这与在xterm direclty中输入不太一样,但几乎与直接在bash中输入一样好,所以我希望它能让您更接近您的目标。如果您真的想直接与xterm交互,那么您可能需要
例如:
1号航站楼:
% nc -l 3333 | bash
端子2(此处键入回波hi):
现在您应该看到第一个终端弹出hi
。现在用xterm&
试试。这对我有用
下面是如何在Python中实现自动化。您可能希望添加一些代码,使服务器能够在客户端准备就绪时通知客户端,而不是使用愚蠢的time.sleep
s
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\u CMD
(和xclock
)
上面的设置并不完全安全,因为任何在正确的时间连接到端口的人都可能在远程服务器上运行任意代码,但听起来您无论如何都计划将其用于测试目的。如果您想提高安全性,可以让netcat绑定到127.0.0.1
而不是0.0.0
,设置ssh隧道(运行ssh-L3333:localhost:3333username@remote-host.com
将端口3333上本地接收到的所有通信通过隧道传输到远程主机(host.com:3333),并让Python连接到(“localhost”,3333)
现在,您可以将其与用于浏览器自动化的:
按照中的说明进行操作,即下载selenium standalone server jar文件,将其放入/path/to/some/place
(服务器上)和pip install-U selenium
(服务器上)
接下来,将以下代码放入/path/to/some/place
中的selenium example.py
:
#!/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进行雅虎搜索。您可能还想增加时间。睡眠
如果您想运行更多程序,可以在运行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发送{mouse | keyboard}事件”以找到更通用的方法。说到这里,但我相信还有很多
如果远程端没有即时响应,您可能希望在Wireshark中嗅探您的网络流量,并检查TCP是否正在对数据进行批处理,而不是逐行发送数据(这里的\n
似乎有帮助,但我想没有保证)。如果是这样的话,你可能是,但是。我希望你不需要走那么远;-)
还有一个注意事项:如果您需要与CLI程序的STDIN/STDOUT通信,您可能希望了解expect脚本(例如,使用,或者对于简单的情况,您可以使用subprocess.Popen.communicate)()。您所说的“在终端中键入”是什么意思?如果它通过X11发送模拟击键,那么这个练习是(a)奇的(b)硬的(c)相当无意义的,(d)与您发布的代码没有任何关系。如果您只是需要让Firefox以某种方式在xterm中运行,那么您可以使用类似于session.exec_命令('xterm-efox')
@n.m.谢谢。你的命令帮助了我。然而,我的最终目标是以某种方式模仿X11用户的行为。这意味着运行程序、打开文件和做普通用户会做的事情。这意味着除了运行程序外,还需要在一些基本级别上控制程序。为什么要从xterm运行firefox?可能是X会话没有从xterm传播到firefox,firefox也找不到可在其上运行的显示器。xterm应该用于在stdout/stderrLooks上输出文本的命令行应用程序,就像您试图开发终端仿真器一样。
FIREFOX_CMD="cd /path/to/some/place && python selenium-example.py"
# 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)