почему этот скрипт Python не работает? - PullRequest
1 голос
/ 28 февраля 2012

Мой скрипт на Python имеет следующий код:

 1 import subprocess
 2 
 3 # initial 'output' to make
 4 r0 = 21
 5 # number of runs to make
 6 rn = 10
 7 
 8 rf = r0+rn
 9 
10 for i in range(r0, rf):
11   #output directory
12   opt_dir = 'output'+str(i)
13   #put it in this output directory
14   popt_dir = './output'+str(i)
15 
16   subprocess.call(['mkdir', opt_dir])
17   subprocess.call(['./exp_fit', 'efit.inp'])
18   subprocess.call(['mv', 'at*', popt_dir])

Намерение таково:

У меня есть программа с именем "exp_fit", которая принимает входной файл "efit.inp".один вызов ./exp_fit efit.inp создаст выходные файлы с именами 'at0_l0_l0', 'at0_l1_l-1', ... и т. д. (всего 475 файлов, начинающихся с 'at').

сейчас я генерирую файлы данныхзапустив exp_fit, затем создав выходные каталоги и переместив их в выходные каталоги с помощью следующих команд bash: (например, с 20-м прогоном моего кода)

mkdir output20

mv at* ./output20

поэтому я думаю, что мой сценарий должен делать то же самое.однако он выполняет только следующее:

(1) он правильно генерирует все выходные файлы (475 файлов, начинающихся с 'at') (2) он правильно создает нужные каталоги (output21 - output30) (3) itОднако, НЕ правильно перемещать все выходные файлы, начинающиеся с 'at', в нужные каталоги.почему это?не должен ли вызов строки 18 правильно выполнить команду, чтобы переместить все мои файлы, начинающиеся с 'at', в нужный каталог?

должен ли я писать этот скрипт с помощью bash вместо python?что с этим не так?

Ответы [ 3 ]

5 голосов
/ 28 февраля 2012

Не отправляйте subprocess вызовы для вещей, которые вы можете сделать прямо из Python.Для перемещения файлов / каталогов просто используйте os.rename.

. Для создания каталога используйте os.mkdir.

. Для запуска внешней программы используйте subprocess is правильный инструмент.

3 голосов
/ 28 февраля 2012

Проблема в том, что эта команда подпроцесса

subprocess.call(['mv', 'at*', './output20'])

- это не то же самое, что набирать это в приглашении

$ mv at* ./output20

В последнем случае расширение bash glob преобразует один аргумент at* в список аргументов с совпадающими именами файлов для команды mv. Так что второе ядро ​​видит как

['mv', 'at0_l0_l0', 'at0_l1_l-1', './output20']

kev's answer говорит Python пропустить команду через оболочку, поэтому произойдет экранирование.

Но лучшее решение - использовать модуль glob и библиотеки os.rename, а не вызывать подпроцесс. Создание подпроцессов стоит дорого, и использование shell=True может привести к дырам в безопасности, поэтому лучше избегать этой привычки.

(На самом деле, я предлагаю создать выходной каталог, переключиться на него, а затем запустить программу exp_fit из этого каталога. Тогда вам не нужно будет перемещать вывод. Сначала попробуйте.)

1 голос
/ 28 февраля 2012

Если shell=True, исполняемый аргумент указывает, какую оболочку использовать.
В Unix оболочкой по умолчанию является /bin/sh.

subprocess.call(['mv', 'at*', popt_dir], shell=True)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...