I have a script _testing_.py containing just raise SystemExit. When I run it from cmdline using py -i _testing_.py, the traceback is printed and the the prompt >>> is printed. However when I run it as subprocess via Popen, i.e. Popen("py -i _testing_.py", stdin=PIPE, stdout=PIPE, stderr=PIPE).communicate() the resulting stderr contains first the prompt >>> and then the traceback. Can you confirm this behaviour and explain it? I'm using Python 3.3.2 on Windows.
It seems thats it's dependent bahaviour. #jentyk's observation is that the order isn't exchanged in Python 2.7 on MacOS.
Related
I use conda to create a Python 2.7 environment including the R package. If I open a Python session in a console, I can check that R is indeed installed with the Popen constructor:
$ python
>>> from subprocess import Popen, PIPE
>>> proc = Popen(["which", "R"], stdout=PIPE, stderr=PIPE)
>>> proc.wait()
0
where the 0 means it is installed. But if I try the same commands from within a Sublime Text 3 REPL running under the exact same Python environment, I get a 1.
Why is this and how can I fix it?
You need to communicate:
proc = Popen(['which', 'python'], stdout=PIPE)
proc.communicate()
('/Users/Kelvin/virtualenvs/foo/bin/python\n', None)
wait just waits for the subprocess to complete and gives you the return code (which is 0 if its successful)
if you get a different error code (1 meaning it failed), I'd look into confirming your virtual environment. try sys.executable
I am trying to run python abaqus through the command prompt using
os.system('abaqus CAE noGUI=ODBMechens')
It doesn't seem to run anything, but if I go to the command prompt myself and type in
abaqus CAE noGUI=ODBMechens
it works. I am using python 2.7 on Windows 10.
Thanks
try using the subprocess module (it's newer) instead:
for example,
subprocess.call(["ls", "-l"])
and in your example, it would be:
subprocess.call('abaqus CAE noGUI=ODBMechens')
More info on the difference between subprocess module and using os.system call:
The Difference between os.system and subprocess calls
You should add before your code
import os
import subprocess
try:
os.environ.pop('PYTHONIOENCODING')
except KeyError:
pass
And then:
cmd = subprocess.Popen('abaqus CAE noGUI=ODBMechens',cwd=jobPath, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, shell=True).communicate()[0]
Variable cmd contains your output. I found that this way it works.
I am running a python script which is using subprocess to execute "history" command on my Ubuntu terminal. Apparently,I am getting this error
history: not found
I got to know that history can not be invoked by any script by default.
What can I do to overcome this? Or any other possible alternatives.
readline.get_history_item() method isnt working either.
Use this:
from subprocess import Popen, PIPE, STDOUT
e = Popen("bash -i -c 'history -r;history' ", shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT)
output = e.communicate()
I have a python script that I am using to call a bash script that renames a file. I then need the new name of the file so python can do some further processing on it. I'm using subprocess.Popen to call the shell script. The shell script echos the new file name so I can use stdout=subprocess.PIPE to get the new file name.
The problem is that sometimes the bash script tries to rename the file with it's old name depending on the circumstances and so gives the message that the two files are the same from the mv command. I have cutout all the other stuff and included a basic example below.
$ ls -1
test.sh
test.txt
This shell script is just an example to force the error message.
$ cat test.sh
#!/bin/bash
mv "test.txt" "test.txt"
echo "test"
In python:
$ python
>>> import subprocess
>>> p = subprocess.Popen(['/bin/bash', '-c', './test.sh'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
>>> p.stdout.read()
"mv: `test.txt' and `test.txt' are the same file\ntest\n"
How can I ignore the message from the mv command and only get the output of the echo command? If all goes well the only output of the shell script would be the result of the echo so really I just need to ignore the mv error message.
Thanks,
Geraint
Direct stderr to null, Thusly
$ python
>>> import os
>>> from subprocess import *
>>> p = Popen(['/bin/bash', '-c', './test.sh'], stdout=PIPE, stderr=open(os.devnull, 'w'))
>>> p.stdout.read()
To get subprocess' output and ignore its error messages:
#!/usr/bin/env python
from subprocess import check_output
import os
with open(os.devnull, 'wb', 0) as DEVNULL:
output = check_output("./test.sh", stderr=DEVNULL)
check_output() raises an exception if the script returns with non-zero status.
See How to hide output of subprocess in Python 2.7.
I've installed the Ruby gem 'haml' on my mac, which I can use to compile haml files into html files using the following command at the terminal:
haml 'path/to/haml/file.haml' 'desired/html/path/file.html'
This command simply creates an html file at the second path, and gives no output in the terminal. So for example, this command:
haml "/Volumes/Macintosh HD/Users/me/Sites/ICSP/sugar.haml" "/Volumes/Macintosh HD/Users/me/Sites/ICSP/sugar.html"
Creates a sugar.html file at the given path. Now I'm trying to use this functionality from a python script. When I type this into IDLE's interactive python shell:
>>>import subprocess
>>>subprocess.Popen('haml "/Volumes/Macintosh HD/Users/me/Sites/ICSP/sugar.haml" "/Volumes/Macintosh HD/Users/me/Sites/ICSP/sugar.html"', shell=True, executable='/bin/bash')
<subprocess.Popen object at 0x159d6f0>
I get output suggesting that the process has been run, however, there is no file outputted. Why is this happening? I even put in the Shell argument, but no interactive shell shows up. Also, I read somewhere that the default shell used is not bash, which is what the Mac terminal uses, so I put that in too for good measure.
Following icktoofay's advice, I ran check_call. Here is the traceback I received:
Traceback (most recent call last):
File
"/Users/neil/Desktop/subprocesstest.py",
line 7, in
p = subprocess.check_call(x, shell=True) File
"/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py",
line 504, in check_call
raise CalledProcessError(retcode, cmd) CalledProcessError: Command 'haml
"/Volumes/Macintosh
HD/Users/neil/Sites/ICSP/sugar.haml"
"/Volumes/Macintosh
HD/Users/neil/Sites/ICSP/sugar.html"'
returned non-zero exit status 127
According to the bash reference manual, while searching for a command to be executed,
If the name is neither a shell
function nor a builtin, and contains
no slashes, Bash searches each element
of $PATH for a directory containing an
executable file by that name. ... If
that function is not defined, the
shell prints an error message and
returns an exit status of 127.
However, I thought it was indeed finding the haml command after adding the shell and executable arguments, because before that, it was giving a 'file or directory not found error', which indicates that the function is not executable directly but rather in a shell only.
Now how do I make python find this haml command? Or would I have to use some ugly workaround like an applescript which then invokes the haml command.
I see that you are using, shell=True, so I would have expected things to just work. Checked it locally here with Python 2.7.1 and haml 3.1.1 and I had no problems executing it. There are also some python implementations you might be interested in, PyHAML, HamlPy, djaml or django-haml.
import subprocess
subprocess.Popen(['haml', 'hello.haml', 'hello.html'], shell=True)
% cat hello.html
<strong class='code' id='message'>Hello, World!</strong>
shlex.split() is your friend, when you want to build args list suitable for Popen and its ilk.
>>> import subprocess
>>> import shlex
>>> p = subprocess.Popen(shlex.split('haml "/Volumes/Macintosh HD/Users/me/Sites/ICSP/sugar.haml" "/Volumes/Macintosh HD/Users/me/Sites/ICSP/sugar.html"'))
>>> p.wait()
0