Interaction between Python script and linux shell

I have a Python script that should interact with the user through the command line, while recording everything that is output.

I currently have this:

# lots of code

popen = subprocess.Popen(
    args,
    shell=True,
    stdin=sys.stdin,
    stdout=sys.stdout,
    stderr=sys.stdout,
    executable='/bin/bash')

popen.communicate()

# more code

Executes a shell command (for example, adduser newuser02) in the same way as when entering it in the terminal, including interactive behavior. It's good.

Now I want to write everything inside the Python script that appears on the screen. But I can't get this part to work.

I tried various ways to use subprocess.PIPE, but usually it interferes with interactivity, for example, it doesn't display query strings.

I also tried various ways to directly change the behavior of sys.stdout, but since the subprocess writes directly to sys.stdout.fileno (), all of this was useless.

+4
2

Popen - - , / , , . . Q: (popen())?.

script , pty.spawn(), . Python python :

#!/usr/bin/env python
import os
import pty
import sys

with open('log', 'ab') as file:
    def read(fd):
        data = os.read(fd, 1024)
        file.write(data)
        file.flush()
        return data

    pty.spawn([sys.executable, "test.py"], read)

pexpect :

import sys
import pexpect # $ pip install pexpect

with open('log', 'ab') as fout:
    p = pexpect.spawn("python test.py")
    p.logfile = fout # or .logfile_read
    p.interact()

( ), stdout stderr, subprocess:

#!/usr/bin/env python
import sys
from subprocess import Popen, PIPE, STDOUT

with open('log','ab') as file:
    p = Popen([sys.executable, '-u', 'test.py'],
              stdout=PIPE, stderr=STDOUT,
              close_fds=True,
              bufsize=0)
    for c in iter(lambda: p.stdout.read(1), ''):
        for f in [sys.stdout, file]:
            f.write(c)
            f.flush()
    p.stdout.close()
    rc = p.wait()

stdout/stderr , teed_call() from Python ?

+2

import subprocess
f = open('file.txt','w')
cmd = ['echo','hello','world']
subprocess.call(cmd, stdout=f)
0

Source: https://habr.com/ru/post/1530218/


All Articles