Run a Python script from another background Python script

77 views Asked by At

I am trying to make an updater. I have made the main program call a file updater.py, which runs hidden as I do not want to disturb the execution of the main program.

The updater.py file then checks if an update is available by connecting to a GitHub repository, and accessing a .txt file inside it, and checks if the __version__ identifier of the main program is less than the latest version. If yes, then the program calls installer.py, which needs to be a visible process to interact with the user.

In main.py, I have written the following line:

Popen([sys.executable, 'updater.py'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) # Start the updater

This works as expected and updater.py runs in the background.

In updater.py, I have written:

Popen([sys.executable, 'installer.py', latestVersion], stdin=subprocess.STDOUT, stdout=subprocess.STDOUT, stderr=subprocess.STDOUT, shell=True)

But this does not run installer.py. It instead gives the following error:

Traceback (most recent call last):
  File "E:\Updated\updater.py", line 18, in <module>
    Popen([executable, 'installer.py', latestVersion], stdin=subprocess.STDOUT, stdout=subprocess.STDOUT, stderr=subprocess.STDOUT, shell=True)
  File "C:\Users\<user>\AppData\Local\Programs\Python\Python311\Lib\subprocess.py", line 992, in __init__
    errread, errwrite) = self._get_handles(stdin, stdout, stderr)
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\<user>\AppData\Local\Programs\Python\Python311\Lib\subprocess.py", line 1361, in _get_handles
    p2cread = msvcrt.get_osfhandle(stdin)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^
OSError: [Errno 9] Bad file descriptor

I don't know what the problem and it would be really helpful if anyone knows something. Thank you.

1

There are 1 answers

4
Booboo On

In updater.py you have:

Popen([sys.executable, 'installer.py', latestVersion], stdin=subprocess.STDOUT, stdout=subprocess.STDOUT, stderr=subprocess.STDOUT, shell=True)

This should be:

Popen([sys.executable, 'installer.py', latestVersion], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)

Update

If you want the user to be able to communicate with installer.py via the console, then you may not want to be specifying stdin=subprocess.PIPE, which would expect "console input" for installer.py to be specified programmatically in updater.py. Anyway, if you want the code to run visibly (it appears you are using Windows), then try:

Popen(
    [
        'cmd',
        '/C',
        sys.executable,
        'installer.py',
        latestVersion
    ],
    stdin=subprocess.PIPE,
    stdout=subprocess.PIPE,
    stderr=subprocess.PIPE,
    shell=True
)