Python子进程通过客户端/服务器更改目录 [英] Python subprocess change dir via client/server
问题描述
我正在尝试通过现有客户端上的套接字库远程更改 cwd,但每次发送实际命令cd .."时我都会遇到麻烦.
I am trying to remotely change the cwd via socket lib on existing client, but I am running into the trouble every time I send the actual command "cd ..".
服务器:
import socket, subprocess, os, sys
s = socket.socket()
host = socket.gethostname()
ip = socket.gethostbyname(host)
port = 8080
s.bind((ip,port))
s.listen(5)
c, a = s.accept()
fr = c.recv(10000)
cwd = fr
print("IP: "+str(a[0])+":"+str(a[1])+"\tCONNECTED")
while True:
cmd = raw_input("\n"+cwd+"> ")
if cmd != "":
c.sendall(cmd)
data = c.recv(1024)
print("\n"+data)
if cmd == "cd ..":
c.sendall(cmd)
cwd = c.recv(1024)
客户:
import socket, subprocess, os, sys
i = 1
cwd = os.getcwd()
while 1:
s = socket.socket()
host = socket.gethostname()
ip = socket.gethostbyname(host)
port = 8080
try:
s.settimeout(5)
s.connect((ip,port))
s.settimeout(None)
s.sendall(cwd)
i = 1
while i == 1:
cmd = s.recv(10000)
if cmd != "over":
sp = subprocess.Popen(cmd, shell=True, cwd=cwd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
out = sp.stdout.read()+"_________________________________"
msg = out + sp.stderr.read()
s.sendall(msg)
if cmd == "over":
s.close()
i = 0
if cmd == "cd ..":
j = 0
k = 0
for i in cwd:
if i == '/':
k = j
j = j + 1
cd = cwd[0:k]
subprocess.Popen('echo', shell=True, cwd=cd)
s.sendall(cd)
print(cd)
except socket.error:
continue
这是我得到的错误:
Traceback (most recent call last):
File "PycharmProjects/server-client/test_hq.py", line 25, in <module>
c.sendall(cmd)
File "/usr/lib/python2.7/socket.py", line 228, in meth
return getattr(self._sock,name)(*args)
socket.error: [Errno 104] Connection reset by peer
我无法弄清楚似乎是什么问题...
I can't figure it out what seems to be the problem...
推荐答案
这个应该更接近你想要的,接收和发送一次比重复发送和接收相同的命令简单很多:
This should be closer to what you want, it is a lot simpler to receive and send once instead of repeatedly sending and receiving the same commands:
Client.py:
import socket, subprocess, os, sys
cwd = os.getcwd()
def make_socket():
s = socket.socket()
host = socket.gethostname()
ip = socket.gethostbyname(host)
port = 8080
s.settimeout(5)
s.connect((ip, port))
s.settimeout(None)
s.sendall(cwd)
return s
while True:
s = make_socket()
try:
while True:
cmd = s.recv(10000)
if cmd == "cd ..":
# os.chdir("..") # uncomment to actually change directory
cd = cwd.rsplit(os.sep(), 1)[0]
subprocess.Popen('echo', shell=True, cwd=cd)
s.sendall(cd)
elif cmd != "over":
sp = subprocess.Popen(cmd, shell=True, cwd=cwd, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
stdin=subprocess.PIPE)
out = sp.stdout.read() + "_________________________________"
msg = out + sp.stderr.read()
s.sendall(msg)
else:
print("closed")
s.close()
sys.exit(0)
except socket.error as e:
print(e)
break
server.py:
import socket, subprocess, os, sys
s = socket.socket()
host = socket.gethostname()
ip = socket.gethostbyname(host)
port = 8080
s.bind((ip,port))
s.listen(5)
c, a = s.accept()
fr = c.recv(10000)
cwd = fr
print("IP: "+str(a[0])+":"+str(a[1])+"\tCONNECTED")
while True:
cmd = raw_input("\n"+cwd+"> ")
if cmd == "cd ..":
print("sending 2")
c.sendall(cmd)
# os.chdir("..") # uncomment to change dir
cwd = c.recv(10000)
elif cmd != "":
print("sending 1")
c.sendall(cmd)
data = c.recv(10000)
print("\n"+data)
如果你想在服务器端处理客户端关闭套接字和 sys.exit(0) 你应该在服务器端捕获 socket.error 以避免管道损坏错误.
If you want to handle the client closing the socket and sys.exit(0) on the server side you should catch a socket.error on the server side to avoid a broken pipe error.
try:
while True:
print(os.getcwd(),44444)
cmd = raw_input("\n"+cwd+"> ")
if cmd != "" and cmd != "cd ..":
print("sending 1")
c.sendall(cmd)
data = c.recv(10000)
print("\n"+data)
if cmd == "cd ..":
print("sending 2")
c.sendall(cmd)
# os.chdir("..") # uncomment to change dir
cwd = c.recv(10000)
except socket.error as e:
print("Exception caught for {}".format(e.strerror))
如果你想根据 errno 做不同的事情,你可以在 except 中进行比较:
If you want to do different things based on the errno you can compare in the except:
if e.errno == errno.EPIPE: 即断管等.
所有 errno 都在 errno 文档
All the errno's are listed here in the errno docs
这篇关于Python子进程通过客户端/服务器更改目录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!