holzschu / a-shell

A terminal for iOS, with multiple windows

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Is there a way to make the PTY work in Python?

Emasoft opened this issue · comments

Unfortunately many python programs I use crash with this error about PTY (pseudo terminal):

File "/private/var/containers/Bundle/Application/7560B8C3-C5AF-49CF-87BF-DFA37A1E81F9/a-Shell-mini.
app/Library/lib/python3.11/pty.py", line 64, in _open_terminal
    raise OSError('out of pty devices')
OSError: out of pty devices

You can reproduce the issue with this:

import os
import sys
import pty
import select

def run_command_with_pty(command):
    master_fd, slave_fd = pty.openpty()  # Open a pseudo-terminal
    pid = os.fork()
    
    if pid == 0:  # Child process
        os.setsid()
        os.dup2(slave_fd, 1)
        os.dup2(slave_fd, 2)
        os.close(master_fd)
        os.execvp("bash", ["bash", "-c", command])
    
    else:  # Parent process
        os.close(slave_fd)
        with open("output.log", "ab") as log_file:
            while True:
                r, _, _ = select.select([master_fd], [], [], 0.5)
                if r:
                    data = os.read(master_fd, 1024)
                    if not data:
                        break
                    os.write(1, data)  # Write to stdout
                    log_file.write(data)
                else:
                    continue

        os.waitpid(pid, 0)  # Wait for the command to complete

if __name__ == '__main__':
    #This script writes a log file with the stdout and stderr output from terminal
    # when running yt-dlp, while still printing the terminal output and keeping it interactive.
    cmd = 'yt-dlp https://youtube.com/playlist?list=PLODe67L10pIxkMLDW5hy-_0zGpSBH9pWs&si=E4nwoxdwHm9lelDX --match-filter -'
    run_command_with_pty(cmd)
    

Any idea? For example, without using PTY there is no current way in a-shell to capture and save automatically the terminal output stream to a file. But if you run a shortcut with a-shell, you need such log to understand what happened in case of crashes.

There is no way to fork on iOS. Everything in a-Shell is done by emulating fork() with threads. This works nicely, but it requires rewriting the code that uses fork and fork-like methods, so this code will not work in a-Shell.
For capturing the output stream of a command to a file, I recommand tee, as in: command | tee outputFile.