使用Ubuntu和pty的ioctl不正确

sf6xfgos  于 2023-11-17  发布在  其他
关注(0)|答案(2)|浏览(128)

我正在使用Python编写的终端多路复用器。在基于Ubuntu的发行版上,我看到错误:

bash: cannot set terminal process group (9862): Inappropriate ioctl for device
bash: no job control in this shell
tmp@tmp-VirtualBox:

字符串
在openSuSE和Fedora上,我没有看到ioctl错误,作业控制工作正常。
示例问题:

#!/usr/bin/python3

import subprocess
import sys
import pty
import os

master, slave = pty.openpty()

bashCMD = "bash".split()
p = subprocess.Popen(bashCMD, preexec_fn=os.setsid, stdin=slave, stdout=slave, stderr=slave, universal_newlines=True, shell=True)

while p.poll() is None:
  data = os.read(master, 1026)
  print(str(data))


完整项目:https://bitbucket.org/hackersgame/janit/src/master/

z5btuh9x

z5btuh9x1#

fork()可以在所有平台上工作。
但它并不像pty.openpty()slave那样给予我们写入TTY的权限
为了解决这个问题,我使用了mmap

#write tty device info to memory the child and parent process can read
slaveFd, tmpfile = tempfile.mkstemp()
os.write(slaveFd, b'\x00' * mmap.PAGESIZE)
os.lseek(slaveFd, 0, os.SEEK_SET)
def getSlaves():
  raw = getSlavesRaw()
  returnData = []
  for lessRaw in raw.strip('/').split('/'):
    returnData.append("/dev/pts/" + str(lessRaw))
  return returnData

def getSlavesRaw():
  os.lseek(slaveFd, 0, os.SEEK_SET)
  buf = mmap.mmap(slaveFd, mmap.PAGESIZE, mmap.MAP_SHARED, mmap.PROT_READ)
  msg = str(buf.readline())
  msg = ':'.join(msg.split(':')[:-1]).split("'")[-1]
  return(msg)

def addSlave(PID):
  offset = getSlavesRaw()
  offset = len(offset)
  os.lseek(slaveFd, offset, os.SEEK_SET)
  buf = mmap.mmap(slaveFd, mmap.PAGESIZE, mmap.MAP_SHARED, mmap.PROT_WRITE)
  TTY = subprocess.check_output(['ps', 'hotty', str(PID)]).strip().decode()
  TTY = TTY.split("pts")[-1] + ":" # cut off pts and add a : for spacing
  for index in range(offset, offset + len(TTY)):
    buf[index] = ord(TTY[index - offset])

#Thanks! https://stackoverflow.com/a/52157066/5282272
# fork this script such that a child process writes to a pty that is
# controlled or "spied on" by the parent process

(child_pid, newMasterHandle) = pty.fork()
masters.append(newMasterHandle)
# A new child process has been spawned and is continuing from here.
# The original parent process is also continuing from here.
# They have "forked".

if child_pid == 0:
  debug("This is the child process fork, pid %s" % os.getpid())
  addSlave(os.getpid())
  bashProcessList.append(subprocess.run("bash"))
else:
  debug("This is the parent process fork, pid %s" % os.getpid())
  debug(getSlaves())

  while True:
    try:
      data = os.read(masters[myScreen], 1026)
    except Exception:
      #time.sleep(.2)
      continue
    yield data

字符串

hmmo2u0o

hmmo2u0o2#

在你最初的例子中,修改这一行:

p = subprocess.Popen(..., shell=True)

字符串
致:

p = subprocess.Popen(..., shell=False)


然后,不再有关于“设备的ioctl不适当”的警告。

相关问题