3

Attempting to convert an old bash script to python. The trouble is that I do not know very much about bash. Is there an equivalent python command for the bash command eval? Eval is used in the bash program like this:

eval "(/usr/path/exec/file) &"

where "file" is an executable file.

If there is no equivalent can someone provide a decent explanation as to what eval is doing here? I'm sorry if this is rudimentary but this is the first bash script I've ever looked at and I am very confused

Thomas Britton
  • 123
  • 2
  • 8
  • I see no reason to use eval in that line. Or, indeed, to use parentheses. Afaics, the intent is to run the executable in the background. If there is more stuff on that line, please edit the question. – rici Jul 08 '15 at 19:47
  • how do I run ` command: str = f"eval $(opam env --switch={switch} --set-switch)" res = subprocess.run(command.split(), check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)` **inside of python**? – Charlie Parker Dec 14 '22 at 01:34
  • related: https://discuss.ocaml.org/t/is-eval-opam-env-switch-switch-set-switch-equivalent-to-opam-switch-set-switch/10957 – Charlie Parker Dec 14 '22 at 01:55
  • aren't the answers missing `.decode()` for the output? – Charlie Parker Dec 15 '22 at 07:23

3 Answers3

1

Use subprocess.Popen to run a subprocess asynchronously

Example:

from subprocess import Popen
p = Popen(['/usr/path/exec/file'])

do other stuff while subprocess is running, then call

p.terminate()

or

p.wait()

Also check out the docs at https://docs.python.org/2/library/subprocess.html#subprocess.Popen

fferri
  • 18,285
  • 5
  • 46
  • 95
  • how do I run ` command: str = f"eval $(opam env --switch={switch} --set-switch)" res = subprocess.run(command.split(), check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)` **inside of python**? – Charlie Parker Dec 14 '22 at 01:35
  • aren't you missing `.decode()` for the output? – Charlie Parker Dec 15 '22 at 07:23
1

There are a couple of things going on there. First you are running inside a bash subshell, that is the parenthesis part. But probably that's not all that important since no variables are changed inside that subshell.

Next you are running a program and file descriptors are however copied so stdin, stdout, and stderr are the same.

And you are running that in the background.

So let's break these down into Python. As mentioned before, we can ignore the subshell part.

As for running the program, os.system() or subprocess.call is the equivalent of running a command without having to capture or change input or output.

More often you do need to capture output so the equivalent of

 x=$(/path/to/exec/file)

is in Python is

 x = subprocess.check_output('/path/to/exec/file')

See Replacing /bin/sh backquote for more info.

Finally, there is part about running in the background. For that the most equivalent match is subprocess.popen as mentioned in one of the other answers. There is also os.fork() but that doesn't work on all OS's, especially Windows. You might also want to consider using threads.

rocky
  • 7,226
  • 3
  • 33
  • 74
  • What is the difference in bash between using the eval command and just typing a command? Essentially what is the difference between this: eval "(/usr/path/exec/file) &" and this: /usr/path/exec/file – Thomas Britton Jul 08 '15 at 19:55
  • For the specific example given, typing just the command would work fine. Eval is used when you need to construct a command including arguments in a string. But if I have `x='/usr/path/exec/file'`, you also don't need "eval" but can just run `$x`. eval can also be used to unquote quoted strings. – rocky Jul 08 '15 at 20:01
  • how do I run ` command: str = f"eval $(opam env --switch={switch} --set-switch)" res = subprocess.run(command.split(), check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)` **inside of python**? – Charlie Parker Dec 14 '22 at 01:34
  • aren't you missing `.decode()` for the output? – Charlie Parker Dec 15 '22 at 07:23
-2

First I would read through the comments here for a good example.

In short, the eval command is evaluating the input vs executing, but for your example, if you running an executable it would be no different than just executing the command from the CLI. The '&' just tells the process to execute in the background. Look at this for more info.

To execute CLI commands in python you can

import subprocess

There are three commands that you may want to consider.

subprocess.call()
output = subprocess.check_output()
subprocess.Popen()

depending on how fine grained you want. For you code, doing something like:

import subprocess

subprocess.call(["/usr/path/exec/file" , "&"])

should get you going. check_ouput() will return any output from the command and Popen() is for more fine grained control.

Community
  • 1
  • 1
Shane Andrie
  • 129
  • 1
  • 8