И это всё МОЁ

Решил я переписать для тренировки и изучения питона кучу баш скриптов в питон.

И есть у меня одна проблема.
Очень часто в моих баш скриптах есть команды терминала. И они настолько разнообразные, что никакого единого подхода питоном к ним нет. А зачастую и вообще можно только запустить 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 sсript";)
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";)

И не важно вернуться команда с ошибкой или нет, я могу отловить и статус и текст и сделать это очень просто.

Вопрос, вот эта моя уродливая функция: так все мучаются? или есть нормальное решение?








 , , ,