Проблема с python subprocess.check_output vs os.system - PullRequest
0 голосов
/ 25 мая 2018

Итак, я пытаюсь использовать «более новый» подпроцесс для запуска программы на фортране в оболочке bash ... Не уверен, что я делаю неправильно, но если я делаю

result = os.system('./get_cpus -inp ./output_00076 -xc {:.4e} -yc {:.4e} -zc {:.4e} -rad {:.4e}'.format(loc[0],loc[1],loc[2],rad) )

, я получаювывод программы Фортрана (из get_cpus) в результате.Кажется, что кажется, работает нормально ... Но если я делаю:

result = subprocess.check_output(['./get_cpus',
                                 '-inp ./output_00076',
                                 '-xc {:.4e}'.format(loc[0]),
                                 '-yc {:.4e}'.format(loc[1]),
                                 '-zc {:.4e}'.format(loc[2]),
                                 '-rad {:.4e}'.format(rad)])

Я получаю сообщение об ошибке:

./get_cpus -inp ./output_00076 -xc 3.1670e-01 -yc 9.6000e-02 -zc 2.4170e-01 -rad 2.0360e-03
forrtl: severe (59): list-directed I/O syntax error, unit -5, file Internal List-Directed Read
Image              PC                Routine            Line        Source             
get_cpus           0000000000409CD8  Unknown               Unknown  Unknown
get_cpus           000000000042AF2D  Unknown               Unknown  Unknown
get_cpus           0000000000429696  Unknown               Unknown  Unknown
get_cpus           00000000004065E7  get_cpus_IP_read_         280  get_cpus.f90
get_cpus           00000000004029B1  MAIN__                     46  get_cpus.f90
get_cpus           000000000040297E  Unknown               Unknown  Unknown
libc-2.22.so       00007FFFECE456D5  __libc_start_main     Unknown  Unknown
get_cpus           00000000004028A9  Unknown               Unknown  Unknown
Traceback (most recent call last):
  File "findCPUs.py", line 45, in <module>
    '-rad {:.4e}'.format(rad)])
  File "/nasa/pkgsrc/2014Q4/lib/python2.7/subprocess.py", line 573, in check_output
    raise CalledProcessError(retcode, cmd, output=output)
subprocess.CalledProcessError: Command '['./get_cpus', '-inp ./output_00076', '-xc 3.1670e-01', '-yc 9.6000e-02', '-zc 2.4170e-01', '-rad 2.0360e-03']' returned non-zero exit status 59

Где 'CalledProcessError: Command' выглядит хорошо для меня ...

Я пробовал это с помощью 'shell = True', и затем я запускаю программу, но все входные данные отсутствуют, так как код на Фортране возвращает оператор использования (описывающий, что мне нужны входные аргументы),????например -

result = subprocess.check_output(['./get_cpus',
                                 '-inp ./output_00076',
                                 '-xc {:.4e}'.format(loc[0]),
                                 '-yc {:.4e}'.format(loc[1]),
                                 '-zc {:.4e}'.format(loc[2]),
                                  '-rad {:.4e}'.format(rad)],
                                 shell=True, stdin=subprocess.PIPE)

Что я делаю не так ??

1 Ответ

0 голосов
/ 25 мая 2018

С os.system вы сами составляете строку аргумента.Это работает, но уродливо, подвержено внедрению кода и не устойчиво к некоторым аргументам с пробелами, если вы забудете их заключить в кавычки.Так что subprocess - правильный выбор.

Теперь есть требования использовать subprocess со списком аргументов.

Здесь разделение аргументов неверно.Вы включаете 2 аргумента как один (разделенный пробелом), например, здесь:

  '-xc {:.4e}'.format(loc[0]),

этот «аргумент» выдается системе как

"-xc .4555"

(да, с кавычками)и это сбивает с толку разбор аргументов.

fix: правильно разделите аргументы:

result = subprocess.check_output(['./get_cpus',
                                 '-inp','./output_00076',
                                 '-xc','{:.4e}'.format(loc[0]),
                                 '-yc','{:.4e}'.format(loc[1]),
                                 '-zc','{:.4e}'.format(loc[2]),
                                 '-rad','{:.4e}'.format(rad)],
                                 stdin = subprocess.PIPE)

вам тоже не нужно shell=True.Это почти никогда полезно, за исключением быстрых хаков.Часто ничего не решает и является обязательством безопасности (внедрение кода)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...