【问题标题】:Using subprocess.call() to pass commands to execute by cmd使用 subprocess.call() 传递命令由 cmd 执行
【发布时间】:2015-04-16 05:53:49
【问题描述】:

我正在尝试将我的 IP 地址设置为 LAN 网络上的特定地址。

为此,我尝试使用以下方法:

import subprocess
command='netsh interface ipv4 set address name="Local Area Connection* 4" source=static address=192.168.173.234 mask=255.255.255.0 gateway=192.168.0.1'
subprocess.call(["cmd.exe", command])

这导致的唯一结果是启动了一个不执行任何操作的空 cmd.exe。

另外,shell=True 有什么用? 当我尝试使用它时,python 返回一个 SyntaxError

更新:如果我使用:

command='netsh interface ipv4 set address name="Local Area Connection* 4" source=static address=192.168.173.222 mask=255.255.255.0 gateway=192.168.0.1'
subprocess.check_call(["netsh.exe", command])

Python 返回错误:

Traceback (most recent call last):
  File "D:file path", line 8, in <module>
    subprocess.check_call(["netsh.exe", netsh_cmd])
  File "C:\Python27\lib\subprocess.py", line 540, in check_call
    raise CalledProcessError(retcode, cmd)
CalledProcessError: Command '['netsh.exe', 'netsh interface ipv4 set address name="Local Area Connection* 4" source=static address=192.168.173.222 mask=255.255.255.0 gateway=192.168.0.1']' returned non-zero exit status 1

【问题讨论】:

  • 您在 Windows 上吗?为什么要使用单引号?如果将命令 按原样 复制粘贴到运行 cmd.exe(不是 Powershell)的 Windows 控制台中,它是否有效? netsh 是如何实现的——netsh.exe 在哪里?还是内部 cmd.exe 命令(不太可能)?
  • @J.F. Sebastian,我在 Windows 8.1 上,更改了单引号(不知道它在 cmd 中不起作用)。是的,如果我在 cmd.exe(必须以管理员身份运行)/Power Shell(也是管理员)中准确输入我在此处所说的内容,它确实有效。 netsh.exe 位于 C:/Windows/System32/ 中。
  • 您是否尝试过以管理员身份运行建议的 Python 代码(用于调试)? call(command)call(command, shell=True)
  • @J.F. Sebastian 你如何以管理员身份运行 python 代码?与'/user:Administrator'
  • 以与运行成功的 netsh 命令完全相同的方式运行它(用于调试)(打开管理控制台并在那里运行 Python 脚本。如果它有效;您可以寻找提升权限的正确方法)。关于最后一个错误:不要从命令的其余部分拆分 netsh。正如我的回答所建议的那样,完全按照您在命令行上看到的那样将命令作为单个字符串传递。

标签: python-2.7 powershell cmd arguments subprocess


【解决方案1】:

如果the search path 中的某处有netsh.exe(假设您在Windows 上),那么您可以按原样传递命令字符串:

import subprocess

subprocess.check_call(command)

【讨论】:

    【解决方案2】:

    如果你使用一串参数你需要shell=True:

    import subprocess
    command="netsh interface ipv4 set address name='Local Area Connection* 4' source=static address=192.168.173.234 mask=255.255.255.0 gateway=192.168.0.1"
    subprocess.call(command,shell=True)
    

    您可以不使用shell=True,我建议您通过传递参数列表来实现:

    import subprocess
    command = ['netsh', 'interface', 'ipv4', 'set', 'address', 'name=Local Area Connection* 4', 'source=static', 'address=192.168.173.234', 'mask=255.255.255.0', 'gateway=192.168.0.1']
    
    
    subprocess.call( command)
    

    或者让shlex.split为你拆分参数:

    import shlex
    
    subprocess.call(shlex.split(command))
    

    使用check_call 代替 call 也可能更可取,因为如果 check_call 会出现非零退出状态,call 不会引发错误。

    【讨论】:

    • @Mario。那么到底发生了什么?
    • 现在我已经尝试使用 check_call python 返回 CalledProcessError: Command '['netsh', ...]' returned non-zero exit status 1
    • 是的,它工作正常,但只要有另一台计算机连接到我在尝试设置特定 IP 的机器上创建的网络。
    • @J.F.Sebastian,我最初按原样使用该命令,您可以在第一个示例中看到它,并且 OP 说它不起作用。 shell=True 会失败吗?
    • @PadraicCunningham:在这种情况下不应该这样做,除非有其他一些冲突的netsh 程序 (different rules for searching the executable)。转义规则 (what is considered a metacharacter) 也有所不同,但对于给定的命令应该无关紧要。 The exit code 可能会转换为其二进制补码负值。
    猜你喜欢
    • 2021-02-19
    • 2012-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-24
    相关资源
    最近更新 更多