Я открываю сессию s sh, используя subprocess.Popen
с установленным флагом shell=True
. Сценарий запускается systemd как root. Я взял strace из клиента s sh и обнаружил:
ioctl(0, TCGETS, 0xbe87d254) = -1 ENOTTY (Inappropriate ioctl for device)
fcntl64(0, F_GETFL) = 0x20800 (flags O_RDONLY|O_NONBLOCK|O_LARGEFILE)
fcntl64(0, F_SETFL, O_RDONLY|O_LARGEFILE) = 0
ioctl(1, TCGETS, 0xbe87d254) = -1 ENOTTY (Inappropriate ioctl for device)
fcntl64(1, F_GETFL) = 0x802 (flags O_RDWR|O_NONBLOCK)
fcntl64(1, F_SETFL, O_RDWR) = 0
ioctl(2, TCGETS, 0xbe87d254) = -1 ENOTTY (Inappropriate ioctl for device)
fcntl64(2, F_GETFL) = 0x2 (flags O_RDWR)
gettimeofday({tv_sec=1583787257, tv_usec=193031}, NULL) = 0
shutdown(3, SHUT_RDWR) = 0
close(3) = 0
exit_group(0) = ?
+++ exited with 0 +++
Похоже, что стандартные потоки установлены неправильно. Я использую флаг -T
для отключения psuedo-tty. Я думал, что shell=True
установит их.
Когда тот же скрипт запускается из командной строки, соединение остается открытым (возможно, потому что установлены STDIN и STDOUT). Я не проверяю вывод или не предоставляю ввод для процесса, он предназначен исключительно для переадресации портов. Что я должен установить stdin
, stdout
и stderr
в моем вызове Popen
, чтобы предотвратить это? Я пробовал subprocess.PIPE
и пилинг внутри команды оболочки безрезультатно
Я также запускаю это из потока незадолго до его выхода. Может ли это быть как-то связано с этим? Я думал, что Popen
должен был запустить новый процесс (не дочерний процесс), если не были указаны каналы.
Редактировать: Вот звонок Попена:
command = shlex.split("ssh -T -o StrictHostKeyChecking=no " +\
"-o UserKnownHostsFile=/dev/null "+\
"-i identityFile "+\
"-p 64046 user@"+ssh_target+" "\
"-R 64045:127.0.0.1:22 -g " \
"-b " + bind_address)
sshProcess = subprocess.Popen(command, shell=True)