2015-11-27 3 views
0

Я пытаюсь использовать subprocess.check_call() и netsh, чтобы изменить настройки карты NIC на компьютере. В настоящее время используется python 2.7 и Windows7.Проблема с subprocess.check_call() return 1 with netsh

Эта команда успешна, когда я запускаю его в из cmd.exe:

netsh interface ip set address name="Local Area Connection" static 192.168.1.1 255.255.255.0 192.168.1.2 

Этот питон скрипт не удается:

import subprocess  
command = ['netsh','interface','ip','set','address','name="Local Area Connection"','static','192.168.1.1','255.255.255.0','192.168.1.2'] 
result = subprocess.check_call(command) 

И это последняя строка вывода отладочные дал из сценария python выше:

CalledProcessError: Command '['netsh', 'interface', 'ip', 'set', 'address', 'name="Local Area Connection"', 'static', '192.168.1.1', '255.255.255.0', '192.168.1.2']' returned non-zero exit status 1 

Итак, что-то явно не так, и я tr чтобы выяснить, что. Первое, что я хотел бы решить, это то, что означают коды возврата? Надеюсь, я не плотный, но https://python.readthedocs.org/en/v2.7.2/library/subprocess.html#, похоже, не объясняет, что означает код возврата. Я нашел эту ветку, What is the return value of subprocess.call()?, но она дает только общие заявления о кодах возврата вообще. Кто-нибудь знает, как определить значение кодов возврата, относящихся к subprocess.check_call()?

Это поможет мне начать поиск неисправностей, но если у кого-нибудь есть идеи относительно того, почему сценарий терпит неудачу, это было бы весьма полезно. Я попытался использовать «Запуск от имени администратора», чтобы открыть cmd.exe, а затем запустить скрипт python, но результат тот же. Этот поток, похоже, является одной и той же проблемой, но я не вижу разрешения на это: Using subprocess.call() to pass commands to execute by cmd. Я пробовал установить command = netsh interface ip set address name="Local Area Connection" static 192.168.1.1 255.255.255.0 192.168.1.2 и subprocess.check_call(command,shell=True), а также subprocess.check_call(shlex.split(command)), и оба кода возврата '1'.

ответ

1

Код возврата - это очень простой способ для программы заметить системы звонков об успешном выполнении программы. В общем случае код возврата 0 означает, что все работает правильно. Когда-либо другое число считается ошибкой. Теперь, программы могут решить использовать разные коды возврата для различных проблем, а затем предоставить реестр, который возвращает код, означает, какая ошибка, но не так много приложений, которые это делают. Это гораздо более распространено, особенно для программ, ориентированных на человека, таких как netsh, чтобы использовать любой ошибочный код возврата (обычно 1), а затем показывать сообщение об ошибке в выходном файле программы.

Вы должны использовать catch_output вместо того, чтобы захватить выход из netsh, а затем и поймать исключение и посмотреть на сообщение об ошибке от него:

import subprocess  
command = ['netsh', 'interface', 'ip', 'set', 'address', 'name="Local Area Connection"', 'static', '192.168.1.1', '255.255.255.0', '192.168.1.2'] 

try: 
    result = subprocess.check_output(command) 
except subprocess.CalledProcessError as ex: 
    print(ex.returncode, ex.output) 
    raise 

Это должно напечатать вам выход из netsh прежде чем программа прерывается, так что netsh, вероятно, скажет вам, что пошло не так.

Если бы я должен был сделать дикое предположение, я бы сказал, что netsh жалуется на отсутствие прав администратора. Чтобы изменить IP-адрес сетевого интерфейса, вам необходимо повысить его. Поэтому, если ваша программа Python не запущена как администратор, ваш нерешенный подпроцесс также не работает у администратора.

+0

Спасибо за ответ. До этого момента я знал о «обработке ошибок», но на самом деле не использовал его. Нужно начать для лучшей практики, так что приятно иметь повод для этого.К сожалению, в этом случае 'print (ex.returncode, ex.output)' дает выход '(1, None)' ....... не слишком полезно. Не запускает cmd.exe в качестве администратора, а затем выполняет скрипт python оттуда, чтобы ухаживать за администратором? Я делаю еще несколько исследований в этом, поэтому я могу быть уверенным, что я запускаю его как администратора. – jeby

+0

Это очень странно. Это должно по крайней мере дать вам некоторую отдачу. Вы уверены, что вы изменили вызов с 'check_call()' на 'check_output()'? Кроме того, что касается вашей фактической проблемы, это могут быть цитаты вокруг 'name =" Local Area Connection ". Попробуйте просто «name = Подключение по локальной сети». – poke

+0

@poke, кажется, ваша догадка правильная. 'subprocess.list2cmdline' избегает двойных кавычек как' "name = \" Подключение по локальной сети \ "" '. Таким образом, код запуска CRT в netsh.exe не удаляет их при создании массива 'argv'. Они обрабатываются как часть имени интерфейса. – eryksun

0

Похоже, вы пропустили спасаясь символы кавычек в командной строке можно использовать:

import subprocess  
command = ['netsh','interface','ip','set','address','name=\\"Local Area Connection\\"','static','192.168.1.1','255.255.255.0','192.168.1.2'] 
result = subprocess.check_call(command) 
+0

Спасибо за предложение. Я попробовал escape-косые черты, но он дал тот же результат (returncode = 1). Кроме того, я думал, что, используя одиночные кавычки для строки, я мог бы использовать двойные кавычки напрямую без слэш-сбрасывания? Я также ранее пытался использовать двойные кавычки для строки и определенно использовал escape-слэши в этом случае. – jeby