Reputation: 5253
I'm trying to incorporate a simple way to keep track of a periodic mysqldump command I want to run using the os module in python. I've written this, but in testing it doesn't raise the exception, even when the mysqldump command completes with an error. I'm pretty new to python, so I might be approaching this terribly, but I thought I would try to get pointed in the right direction.
db_dump = "mysqldump -u %s -p%s --socket=source_socket --databases %s | mysql -u %s -p%s --socket=dest_socket" % (db_user, db_pass, ' '.join(db_list), db_user, db_pass)
try:
os.system(db_dump)
except:
logging.error("databases did not dump")
else:
logging.info("database dump complete")
Upvotes: 4
Views: 4941
Reputation: 7052
Here is what I would do.
import logging
import subprocess
log = logging.getLogger(__name__)
cmd = "mysqldump -u %s -p%s --socket=source_socket --databases %s | mysql -u %s -p%s " \
"--socket=dest_socket" % (db_user, db_pass, ' '.join(db_list), db_user, db_pass)
process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE.PIPE)
stdout, stderr = process.communicate()
stdout = [x for x in stdout.split("\n") if x != ""]
stderr = [x for x in stderr.split("\n") if x != ""]
if process.returncode < 0 or len(stderr):
for error in stderr:
log.error(error)
Upvotes: 2
Reputation: 76725
os.system()
returns an integer result code. When it returns 0, the command ran successfully; when it returns a nonzero value, that indicates an error.
db_dump = "mysqldump -u %s -p%s --socket=source_socket --databases %s | mysql -u %s -p%s --socket=dest_socket" % (db_user, db_pass, ' '.join(db_list), db_user, db_pass)
result = os.system(db_dump)
if 0 == result:
logging.info("database dump complete")
else:
logging.error("databases did not dump; result code: %d" % result)
Like @COpython, I recommend the use of subprocess
. It is a bit more complicated than os.system()
but it is tremendously more flexible. With os.system()
the output is sent to the terminal, but with subprocess
you can collect the output so you can search it for error messages or whatever. Or you can just discard the output.
Upvotes: 2
Reputation: 3981
os.system is not a very robust or powerful way to call system commands, I'd recommend using subprocess.check_output()
or subprocess.check_call
ie,
>>> cmd = 'ls -l'
>>> badcmd = 'ls /foobar'
>>> subprocess.check_call(cmd.split())
0
>>> subprocess.check_call(badcmd.split())
ls: /foobar: No such file or directory
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 511, in check_call
raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['ls', '/foobar']' returned non-zero exit status 1
Upvotes: 5