Проблема выполнения скрипта с использованием Python и subprocces.call пока работает в Bash - PullRequest
4 голосов
/ 26 мая 2010

Впервые я прошу немного помощи здесь, потому что я больше человек ServerFault.

Я делаю некоторые скрипты на Python и до сих пор люблю этот язык, но у меня есть небольшая проблема, которая не позволяет моему скрипту работать.

Вот строка кода, о которой идет речь:

subprocess.call('xen-create-image --hostname '+nom+' --memory '+memory+' --partitions=/root/scripts/part.tmp --ip '+ip+' --netmask '+netmask+' --gateway '+gateway+' --passwd',shell=True)

Я пробовал то же самое с os.popen. Все переменные установлены правильно.

Когда я выполняю соответствующую команду в своей обычной оболочке Linux, она прекрасно работает, но когда я выполняю ее, используя мои скрипты Python, я получаю странные ошибки. Я даже заменил subprocess.call () на функцию print, чтобы убедиться, что я использую точный вывод команды.

Я посмотрел на переменные окружения моей оболочки, но они почти одинаковы ... Я опубликую ошибку, которую я получаю, но не уверен, что она имеет отношение к моей проблеме.

Использование неинициализированных значений $ lines [0] в подстановке (s ///) в строке /usr/share/perl5/Config/IniFiles.pm 614. Использование неинициализированного значения $ _ в сопоставлении с образцом (m //) в строке /usr/share/perl5/Config/IniFiles.pm 628.

Я не эксперт по Python, поэтому я, скорее всего, что-то здесь упускаю.

Заранее благодарю за помощь,

Antoine


EDIT

Следуя совету miax, я перестал использовать shell = True. Вместо этого я взглянул на документацию по Python для подпроцесса и использовал следующий фрагмент кода:

cmd = 'xen-create-image --hostname '+nom+' --memory '+memory+' --partitions=/root/scripts/part.tmp --ip '+ip+' --netmask '+netmask+' --gateway '+gateway+' --passwd'
args = shlex.split(cmd)
subprocess.call(args)

К сожалению, это ничего не меняет ...


EDIT2

Я использовал подсказку от miax, но я все еще получаю вышеуказанную ошибку ... Вот код, который я использовал.

cmd = ['xen-create-image', '--hostname', nom, '--memory', memory, '--partitions=/root/scripts/part.tmp', '--ip', ip, '--netmask', netmask, '--gateway', gateway, '--passwd']
subprocess.call(cmd)

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

Ответы [ 4 ]

2 голосов
/ 26 мая 2010

Вы (в большинстве случаев) не хотите использовать подпроцесс с shell=True. Передайте ему список аргументов команды. Это

  • более безопасно: представьте, что пользователю удается передать foo; rm -rf /; echo в качестве некоторых значений.
  • более надежно: представьте, что одна из строк содержит $ или что-то еще - она ​​будет расширена оболочкой и заменена содержимым этой переменной среды.

Не зная вашего кода и xen-create-image, я предполагаю, что это является причиной вашей проблемы.

PS: Обязательно посмотрите, равен ли код выхода команды нулю, и действуйте соответствующим образом, если нет. (Если вы уверены, что он всегда будет равен нулю, используйте check_call, который повышается, если этого не происходит; таким образом, по крайней мере, вы будете иметь определенное поведение, если оно потерпит неудачу.)

0 голосов
/ 24 июня 2010

Сценарий xen-create-image начинается с hashbang? То есть первая строка что-то вроде

#!/bin/sh

? Это одна вещь, чтобы проверить. Другое - то, что вы можете попытаться вызвать вашу команду как:

cmd = ['/bin/sh', '-c', 'xen-create-image --hostname %s --memory %s --partitions=/root/scripts/part.tmp --ip %s --netmask %s --gateway %s --passwd' % (nom, memory, ip, netmask, gateway)]
subprocess.call(cmd, shell=False)

Возможно, вы захотите напечатать cmd, чтобы убедиться, что это команда, которую вы намереваетесь выполнить (т.е. проверить замены).

0 голосов
/ 26 мая 2010

Вам нужно print команда, которую вы используете:

cmd = 'xen-create-image --hostname '+nom+' --memory '+memory+' --partitions=/root/scripts/part.tmp --ip '+ip+' --netmask '+netmask+' --gateway '+gateway+' --passwd'
print "COMMAND:", cmd

А затем вставьте команду в вашу оболочку, чтобы убедиться, что она точно такая же.

0 голосов
/ 26 мая 2010

В вашем Edit2 примере, который не работает, вы думаете, , что вы предоставляете следующие опции для xen-create-image:

  • --hostname
  • --memory
  • --partitions=...
  • и т.д.

... но вы на самом деле указываете следующие опции:

  • --hostname пространство
  • пространство --memory пространство
  • пространство --partitions=...
  • и т.д.

У вас есть эта строка:

cmd = ['xen-create-image', '--hostname ', nom, ' --memory ', memory, ' --partitions=/root/scripts/part.tmp', ' --ip ', ip, ' --netmask ', netmask, ' --gateway ', gateway, ' --passwd']

Но вам нужно убрать лишние пробелы:

cmd = ['xen-create-image', '--hostname', nom, '--memory', memory, '--partitions=/root/scripts/part.tmp', '--ip', ip, '--netmask', netmask, '--gateway', gateway, '--passwd']
...