Решил я переписать для тренировки и изучения питона кучу баш скриптов в питон.
И есть у меня одна проблема.
Очень часто в моих баш скриптах есть команды терминала. И они настолько разнообразные, что никакого единого подхода питоном к ним нет. А зачастую и вообще можно только запустить bash код из Питона.
В связи с этим я решил, что почти все команды буду запускать саб процессом из питона.
Но и тут меня встретила жопа с тем, что мне нормально не отловить вывод команды или ее ошибку переменную или в print.
os.system - не отлавливает ошибки
subprocess.check_output - не тоже не отдает то ли ошибку,то ли вывод.
Единственное, что более менее работает это
p = Popen(command)
p = Popen(cmd, stdout=subprocess.PIPE,stderr=PIPE,shell=True,
universal_newlines=True)
output, error = p.communicate()
но и тут проблемы.
Если я делаю return, то не вижу вывода и должен делать
x=function_name(cmd)
print(x)
А если я делаю print , то не могу засунуть output в переменную.
В результате у меня родилась уродливая по моему мнению функция, в которую помимо команды я вынужден запихивать метод, корым она мне будет отдавать stdout.
вот она:
def run_command(cmd,output="print",exit_on_error=False):
p = Popen(cmd, stdout=subprocess.PIPE,stderr=PIPE,shell=True,
universal_newlines=True)
o, e = p.communicate()
if p.returncode != 0:
if output == "print" : print("%s%s" % (o, e))
if exit_on_error:
print("Error. Exit script")
quit()
if output == "return": return("%s%s" % (o, e))
else:
if output == "return": return("%s%s" % (o, e))
print("%s%s" % (o, e))
И если я хочу вывод на экран, то
cmd='команда'
run_command(cmd,"print")
А если я хочу вывод в переменную, то
cmd='команда'
x=run_command(cmd,"return")
В если я хочу выйти из скрипта при ошибке, то
run_command(cmd, "print", True)
Тогда как в баше, я получаю вывод в переменную или на экран в зависимости от того просто я запуская команды или запускаю ее в переменную.
Например:
last_remote=$(ssh $backup_ip "/sbin/zfs list -t snapshot -o name | grep "$remote_dataset""@""$type" | sort -r | head -1")
или просто
$(ssh $backup_ip "/sbin/zfs list -t snapshot -o name | grep "$remote_dataset""@""$type" | sort -r | head -1")
И не важно вернется команда с ошибкой или нет, я могу отловить и статус и текст и сделать это очень просто.
Вопрос, вот эта моя уродливая функция: так все мучаются? или есть нормальное решение?