0

I would like to run a python script from another python script using subprocess.Popen(). When I try in my terminal python3 eclat_model.py -p -c raw_data_430.csv -C out-eclat_430.csv -m 100 everything works. But when I insert in the script.py following code:

import subprocess

subprocess.Popen(
        "eclat_model.py -p -c raw_data_430.csv -C out-eclat_430.csv -m 100"
    )

I got this error message:

Traceback (most recent call last):
  File "run_eclat.py", line 68, in <module>
    main()
  File "run_eclat.py", line 46, in main
    subprocess.Popen(
  File "/usr/lib/python3.8/subprocess.py", line 858, in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
  File "/usr/lib/python3.8/subprocess.py", line 1704, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: 'eclat_model.py -p -c raw_data_430.csv -C out-eclat_430.csv -m 100'

How can I fix it please?

vojtam
  • 1,157
  • 9
  • 34
  • You need to pass a list of arguments (not a single string); you can use [shlex.split](https://docs.python.org/3/library/subprocess.html#popen-constructor) to split the command. – Ionut Ticus Jul 20 '22 at 12:01
  • @IonutTicus Not strictly true. `Popen` can deal fine with a string command line (so long as `shell=True`). – AKX Jul 20 '22 at 12:03

1 Answers1

1

There is no eclat_model.py executable on your PATH, so it can't be executed directly.

If the script has been marked executable and contains a suitable shebang line, you could do ./eclat_model.py, but in case you want to be safe: if you want to use the same Python interpreter you're using for the current script, you can find it in sys.executable.

I also split your arguments into a list here, so it's safer to e.g. add user input in there without causing a shell injection vulnerability.

import sys
import subprocess

subprocess.Popen(
    [
        sys.executable,
        "eclat_model.py",
        "-p",
        "-c",
        "raw_data_430.csv",
        "-C",
        "out-eclat_430.csv",
        "-m",
        "100",
    ],
    shell=False,
)
AKX
  • 152,115
  • 15
  • 115
  • 172
  • Calling Python from Python is separately an antipattern. In the vast majority of cases, you want to simply `import` the code and run a function in the current process. – tripleee Jul 20 '22 at 12:05
  • @tripleee Generally yes, but this has the benefit that you can e.g. kill the subprocess (after a timeout, perhaps), and it can e.g. separately run out of memory without taking the other process with it. (Considering there's `_model` in the filename, it sounds like it could.) – AKX Jul 20 '22 at 12:07