I have next code, it will do next:
- subprocess for
ssh -f -Mto let ssh launch a shared socket in background - As above is in background, so for the second ssh connection we could just reuse the socket
/tmp/control-channelto connect ssh server without password.
test.py:
import subprocess
import os
import sys
import stat
ssh_user = "my_user" # change to your account
ssh_passwd = "my_password" # change to your password
try:
os.remove("/tmp/control-channel")
except:
pass
# prepare passwd file
file = open("./passwd","w")
passwd_content = f"#!/bin/sh\necho {ssh_passwd}"
file.write(passwd_content)
file.close()
os.chmod("./passwd", stat.S_IRWXU)
# setup shared ssh socket, put it in background
env = {'SSH_ASKPASS': "./passwd", 'DISPLAY':'', 'SSH_ASKPASS_REQUIRE':'force'}
args = ['ssh', '-f', '-o', 'LogLevel=ERROR', '-x', '-o', 'ConnectTimeout=30', '-o', 'ControlPersist=300', '-o', 'UserKnownHostsFile=/dev/null', '-o', 'StrictHostKeyChecking=no', '-o', 'ServerAliveInterval=15', '-MN', '-S', '/tmp/control-channel', '-p', '22', '-l', ssh_user, 'localhost']
process = subprocess.Popen(args, env=env,
stdout=subprocess.PIPE,
# stderr=subprocess.STDOUT, # uncomment this line to enable stderr will make subprocess hang
stdin=subprocess.DEVNULL,
start_new_session=True)
sout, serr = process.communicate()
print(sout)
print(serr)
# use shared socket
args2 = ['ssh', '-o', 'LogLevel=ERROR', '-o', 'ControlPath=/tmp/control-channel', '-p', '22', '-l', ssh_user, 'localhost', 'uname -a']
process2 = subprocess.Popen(args2,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
stdin=subprocess.DEVNULL)
content, _ = process2.communicate()
print(content)
execution:
$ python3 test.py
b''
None
b'Linux shmachine 4.19.0-21-amd64 #1 SMP Debian 4.19.249-2 (2022-06-30) x86_64 GNU/Linux\n'
So far so good, just if I uncomment stderr=subprocess.STDOUT in the first subprocess, it will hang:
$ python3 test.py
^CTraceback (most recent call last):
File "test.py", line 29, in <module>
sout, serr = process.communicate()
File "/usr/lib/python3.7/subprocess.py", line 926, in communicate
stdout = self.stdout.read()
KeyboardInterrupt
I wonder what's the problem here?
My environment:
$ python3 --version
Python 3.7.3
$ ssh -V
OpenSSH_7.9p1 Debian-10+deb10u2, OpenSSL 1.1.1n 15 Mar 2022
$ cat /etc/issue
Debian GNU/Linux 10 \n \l
from subprocess (launch ssh process in background) communicate hang if enable stderr
No comments:
Post a Comment