3

I have a Mathematica script that I can run as a bash executable from Terminal. I want to run it from within Python and get the result out. This is the code I wanted to use:

proc = subprocess.Popen(["./solve.m", Mrefnorm, Mvert, Mcomp, Mangle],
        stdout=subprocess.PIPE,stderr=subprocess.PIPE)
result, err = proc.communicate()

Unfortunately the result is an empty string. However, when I run this code, the result is printed to the terminal window as I would expect:

proc = subprocess.Popen(["./solve.m", Mrefnorm, Mvert, Mcomp, Mangle],
        stdout=subprocess.sys.stdout,stderr=subprocess.sys.stdout)

I found this answer for someone with windows and it is the exact same problem I am having. Unfortunately his solution related to his firewall software sandboxing the processes. I already disabled mine to check if that would resolve it and it does not. I have tried everything that the commenters mentioned on his question with no success.

In summary, the Mathematica script runs in both cases (takes about 5 seconds for both) but when I use PIPE, I can't get at the output from the script.

Community
  • 1
  • 1
  • http://stackoverflow.com/questions/2715847/python-read-streaming-input-from-subprocess-communicate – agentp Feb 06 '14 at 13:12
  • Thank-you for the response; I tried the solution from that post and I still get a null string from the PIPE of stdout. I am trying to get hold of another computer in the meanwhile to try the scripts out on. – Conrad Rosenbrock Feb 06 '14 at 17:19
  • 1
    What is `proc.returncode`? Is it successful? What is in `err`? What is shebang in `./solve.m`? Do you see any output in the terminal? Do you see any output if there is no redirect (stdout/stderr are `None`)? Have you tried to copy-paste the successful command from bash and run it using `subprocess.check_call("./solve.m ...", shell=True)`? Can you redirect the output in bash e.g., `./solve.m ... >some_file` (does `some_file` contain correct output)? Do you use correct working directory (`cwd` parameter)? – jfs Feb 18 '14 at 16:10
  • proc.returncode = 0; err = ''; shebang = "#!/Applications/Mathematica.app/Contents/MacOS/MathematicaScript -script"; No output in terminal when redirected; when stdout=None, the terminal shows the output from the mathematica script with the correct answer from the math problem. When I run it directly in bash it also works correctly. subprocess.check_call with no redirects and the same shell command that works in bash also works and print the result to the terminal. However, if I use check_output, it returns a null string again because it internally redirects to PIPE. – Conrad Rosenbrock Feb 19 '14 at 22:20

3 Answers3

2

Turns out there is a bug in Mathematica 9 with redirecting stdout. See https://mathematica.stackexchange.com/questions/20954/why-doesnt-my-script-work-when-i-redirect-stdout

Community
  • 1
  • 1
Wayne Allen
  • 832
  • 4
  • 11
1

I'm not sure why this is but I made it work like this:

 proc=subprocess.Popen('fullpath/math -initfile  fullpath/script.m' ,
        shell=True,
        stdout=subprocess.pipe )

For some reason the list form of the arg list does not work, and -script does not work.

Just checked you can pass extra arguments just fine adding to the string

 proc=subprocess.Popen('fullpath/math -initfile  fullpath/script.m arg1 arg2' ,
        shell=True,
        stdout=subprocess.pipe )

access the arguments in your script via $CommandLine

(mathematica 9, python 2.4.3, redhat )

agentp
  • 6,528
  • 2
  • 16
  • 34
  • thank-you for the example. I tried it and got the same behavior (empty PIPE), so I am pretty sure something must be wrong with my installation on my machine. I appreciate your effort. – Conrad Rosenbrock Feb 06 '14 at 23:09
1

If Mathematica doesn't like a redirected stdout then you could try to hoodwink it by providing a pseudo-tty:

import pipes
from pexpect import run # $ pip install pexpect

args = ["./solve.m", Mrefnorm, Mvert, Mcomp, Mangle]
command = " ".join(map(pipes.quote, args))
output, status = run(command, withexitstatus=True)

You could also use stdlib pty module directly to capture the output.

If you want to get separate stdout/stderr; you could try to workaround the bug mentioned by @Wayne Allen.

Community
  • 1
  • 1
jfs
  • 346,887
  • 152
  • 868
  • 1,518