Get subprocess error output from shell command

B

Benjamin Kaplan

I'm running a shell command like:
plutil -convert xml1 "~/Library/Preferences/iCab/iCab 4 Bookmarks"

Getting error:
~/Library/Preferences/iCab/iCab 4 Bookmarks: Permission denied

How would I capture this error using a method of subprocess?

I read the doc at
http://docs.python.org/release/3.0.1/library/subprocess.html

but confess I don't understand it.

-- Gnarlie
http://Gnarlodious.com/
--

Yeah, the subprocess docs are a bit confusing. Here's what you need to do.



from subprocess import Popen, PIPE

#create a Popen object
#note that I'm putting the command in a list
#the stdout=PIPE thing says I want to capture it
process = Popen( ['plutil', '-convert', 'xml1',
'~/Library/Preferences/iCab/iCab 4 Bookmarks'], stdout = PIPE, stderr
= PIPE)

#then, you communicate with the process

outdata, errdata = process.communicate()
 
C

Chris Rebert

I'm running a shell command like:
plutil -convert xml1 "~/Library/Preferences/iCab/iCab 4 Bookmarks"

Getting error:
~/Library/Preferences/iCab/iCab 4 Bookmarks: Permission denied

How would I capture this error using a method of subprocess?

I read the doc at
http://docs.python.org/release/3.0.1/library/subprocess.html

but confess I don't understand it.

from subprocess import Popen, PIPE

target = '~/Library/Preferences/iCab/iCab 4 Bookmarks'
args = ['plutil', '-convert', 'xml1', target]

proc = Popen(args, stdout=PIPE, stderr=PIPE)
output, error_output = proc.communicate()

if proc.returncode: # non-zero exit status, indicating error
print("Encountered error:")
print(error_output) # output the error message

Cheers,
Chris
 
G

Gnarlodious

OK I get it, and that seems like it should work. But when I simulate a
permissions error by setting the file to unwritable I get an error:

outdata, errdata = process.communicate()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Library/Frameworks/Python.framework/Versions/3.1/lib/
python3.1/subprocess.py", line 715, in communicate
return self._communicate(input)
File "/Library/Frameworks/Python.framework/Versions/3.1/lib/
python3.1/subprocess.py", line 1191, in _communicate
stdout, stderr = self._communicate_with_poll(input)
File "/Library/Frameworks/Python.framework/Versions/3.1/lib/
python3.1/subprocess.py", line 1236, in _communicate_with_poll
register_and_append(self.stdout, select_POLLIN_POLLPRI)
File "/Library/Frameworks/Python.framework/Versions/3.1/lib/
python3.1/subprocess.py", line 1223, in register_and_append
poller.register(file_obj.fileno(), eventmask)
ValueError: I/O operation on closed file


Is there a way to trap the last line and handle it instead of crashing
my webapp?

-- Gnarlie
 
G

Gnarlodious

I get it, you instantiate an object, call a method and get a tuple in
response. However, here is what I see:
(b'~/Library/Preferences/iCab/iCab 4 Bookmarks: Permission denied\n',
b'')

So all I get is the string and no error message, which is the same
thing I get with the simpler subprocess.call(). I can parse out the
error out and handle it if I need to. Is this a failing in the OSX
plutil tool?

-- Gnarlie
 
G

Gnarlodious

if proc.returncode: # non-zero exit status, indicating error
    print("Encountered error:")
    print(error_output) # output the error message

Like in my previous post, this only outputs an empty string.
Apparently plutil doesn't communicate well.

-- Gnarlie
 
B

Benjamin Kaplan

I get it, you instantiate an object, call a method and get a tuple in
response. However, here is what I see:

(b'~/Library/Preferences/iCab/iCab 4 Bookmarks: Permission denied\n',
b'')

So all I get is the string and no error message, which is the same
thing I get with the simpler subprocess.call(). I can parse out the
error out and handle it if I need to. Is this a failing in the OSX
plutil tool?

-- Gnarlie
--

Were you expecting a Python error? That's not how POSIX shells work. A
process that fails just gives you a non-zero return code, not an
exception. You can call process.poll() to get the return code.
 
C

Chris Rebert

Were you expecting a Python error? That's not how POSIX shells work. A
process that fails just gives you a non-zero return code, not an
exception. You can call process.poll() to get the return code.

However, using subprocess.check_call() or subprocess.check_output()
will cause a non-zero exit code to raise a Python exception,
CalledProcessError.
http://docs.python.org/library/subprocess.html#subprocess.check_call
http://docs.python.org/library/subprocess.html#subprocess.check_output

Cheers,
Chris
 
C

Chris Rebert

<quote what="earlier relevant post" reason="context">
I get it, you instantiate an object, call a method and get a tuple in
response. However, here is what I see:

(b'~/Library/Preferences/iCab/iCab 4 Bookmarks: Permission denied\n',
b'')

So all I get is the string and no error message,
</quote>

Like in my previous post, this only outputs an empty string.
Apparently plutil doesn't communicate well.

Yes, it seems to output its error message to stdout, rather than
stderr in line with *nix conventions as one would expect.

Cheers,
Chris
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,797
Messages
2,569,647
Members
45,376
Latest member
Coy6815793
Top