I have a Python script that should report success or failure of the previous command. Currently, I'm doing
command && myscript "Success" || myscript "Failed"
What I would like to do is instead to be able to run the commands unlinked as in:
command; myscript
And have myscript
retrieve $?
, i.e. the exist status. I know I could run:
command; myscript $?
But what I'm really looking for is a Python way to retrieve $?
from Python.
How can I do it?
Since this is a strange request, let me clarify where it comes from. I have a Python script that uses the pushover API to send a notification to my phone.
When I run a long process, I run it as process && notify "success" || notify "failure"
. But sometimes I forget to do this and just run the process. At this point, I'd like to run "notify" on the still processing command line, and have it pick up the exit status and notify me.
Of course I could also implement the pushover API call in bash, but now it's become a question of figuring out how to do it in Python.
This may not be possible, because of how a script (of any language, not just Python) gets executed. Try this: create a shell script called retcode.sh
with the following contents:
#!/bin/bash
echo $?
Make it executable, then try the following at a shell prompt:
foo # Or any other non-existent command
echo $? # prints 127
foo
./retcode.sh # prints 0
I'd have to double-check this, but it seems that all scripts, not just Python scripts, are run in a separate process that doesn't have access to the exit code of the previous command run by the "parent" shell process. Which may explain why Python doesn't (as far as I can tell) give you a way to retrieve the exit code of the previous command like bash's $?
— because it would always be 0, no matter what.
I believe your approach of doing command; myscript $?
is the best way to achieve what you're trying to do: let the Python script know about the exit code of the previous step.
Update: After seeing your clarification of what you're trying to do, I think your best bet will be to modify your notify
script just a little, so that it can take an option like -s
or --status
(using argparse to make parsing options easier, of course) and send a message based on the status code ("success" if the code was 0, "failure NN" if it was anything else, where NN is the actual code). Then when you type command
without your little && notify "success" || notify "failure"
trick, while it's still running you can type notify -s $?
and get the notification you're looking for, since that will be the next thing that your shell runs after command
returns.
false; export ret=$?; ./myscript2.py
myscript2.py:
#!/usr/bin/python
import os
print os.environ['ret']
Output:
1
It is clearly not possible: the exit value of a process is only accessible to its parent, and no shells I know offer an API to allow next process to retrieve it.
IMHO, what is closer to your need would be:
process
myscript $?
That way, you can do it even if you started you process without thinking about notification.
You could also make the script able to run a process get the exit code and to its notification, or (depending on options given in command line) use an exit code given as parameter. For example, you could have:
myscript process
: runs process
and does notificationsmyscript -c $?
: only does notificationsargparse
module can make that easy.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With