0

I have a Python program, it generates a string, say fileName. In fileName I hold something like "video1.avi", or "sound1.wav". Then I make an os call to start a program ! program arg1 arg2, where my fileName is arg2. How can I achieve that on the fly, without making the whole program return a single string (the fileName) and then pass it to the shell line? How can I make that during execution. The script executes in Jupyter.

P.S. I am looping and changing the file name and I have to run that script at every loop.

KDX2
  • 727
  • 2
  • 7
  • 25

1 Answers1

3

If you want your script to run some outside program, passing in an argument, the way to do that is the subprocess module.

Exactly which function to call depends on what exactly do you want to do. Just start it in the background and ignore the result? Wait for it to finish, ignore any output, but check that it returned success? Collect output so you can log it? I'm going to pick one of the many options arbitrarily, but read the linked docs to see how to do whichever one you actually want.

for thingy in your_loop:
    fileName = your_filename_creating_logic(thingy)
    try:
        subprocess.run(['program', 'arg1', fileName],
                       check=True)
        print(f'program ran on {filename} successfully')
    except subprocess.CalledProcessError as e:
        print(f'program failed on {filename} with #{e.returncode}')

Notice that I'm passing a list of arguments, with the program name (or full path) as the first one. You can throw in hardcoded strings like arg1 or --breakfast=spam, and variables like fileName. Because it's a list of strings, not one big string, and because it's not going through the shell at all (at least on Mac and Linux; things are a bit more complicated on Windows, but mostly it "just works" anyway), I don't have to worry about quoting filename in case it has spaces or other funky characters.

If you're using Python 3.4 or 2.7, you won't have that run function; just change it to check_call (and without that check=True argument).

abarnert
  • 313,628
  • 35
  • 508
  • 596