【问题标题】:python subprocess.call arguments issuepython subprocess.call参数问题
【发布时间】:2016-05-22 05:40:02
【问题描述】:

我正在 Linux 下编写一个简单的 Python 脚本,以使用 subprocess 对我的子网上的主机执行一批并发单次 ping。

手动命令有效: ping -c 1 192.168.68.1

脚本::

#!/usr/bin/python
from subprocess import call

path = "ping"
flags = "-c 1 "

for i in range(1,3):
    ip_addr = "192.168.68." + str(i)
    args = flags + ip_addr

    print "doing: {} {}".format(path, args)        
    call([path, args])

注释掉调用输出预期:

doing: ping -c 1 192.168.68.1
doing: ping -c 1 192.168.68.2

使用call(),脚本似乎调用了 ping 但参数未知。输出如下:

doing: ping -c 1 192.168.68.1
Usage: ping [-aAbBdDfhLnOqrRUvV64] [-c count] [-i interval] [-I interface]
        [-m mark] [-M pmtudisc_option] [-l preload] [-p pattern] [-Q tos]
        [-s packetsize] [-S sndbuf] [-t ttl] [-T timestamp_option]
        [-w deadline] [-W timeout] [hop1 ...] destination
Usage: ping -6 [-aAbBdDfhLnOqrRUvV] [-c count] [-i interval] [-I interface]
         [-l preload] [-m mark] [-M pmtudisc_option]
         [-N nodeinfo_option] [-p pattern] [-Q tclass] [-s packetsize]
         [-S sndbuf] [-t ttl] [-T timestamp_option] [-w deadline]
         [-W timeout] destination
doing: ping -c 1 192.168.68.2
Usage: ping [-aAbBdDfhLnOqrRUvV64] [-c count] [-i interval] [-I interface]
        [-m mark] [-M pmtudisc_option] [-l preload] [-p pattern] [-Q tos]
        [-s packetsize] [-S sndbuf] [-t ttl] [-T timestamp_option]
        [-w deadline] [-W timeout] [hop1 ...] destination
Usage: ping -6 [-aAbBdDfhLnOqrRUvV] [-c count] [-i interval] [-I interface]
         [-l preload] [-m mark] [-M pmtudisc_option]
         [-N nodeinfo_option] [-p pattern] [-Q tclass] [-s packetsize]
         [-S sndbuf] [-t ttl] [-T timestamp_option] [-w deadline]
         [-W timeout] destination

似乎ping 每次迭代都会被调用两次,args 与我的预期不同。我注意到 ping 抱怨的 -6 参数。
我将不胜感激,尤其是在正确使用 call() 方面。

更新:
添加了我试图模拟的 bash 脚本:

#!/bin/bash
for ip in $(seq 1 2); do
    ping -c 1 192.168.68.$ip &
done

【问题讨论】:

  • call([path, flags.strip(), ip_addr])

标签: python linux subprocess call


【解决方案1】:

传递给函数call 的参数应该是列表中的单个元素,如下所示:

call(['ping','-c','1','192.168.68.2'])

我无法在我的环境中重现“双重打印”。

【讨论】:

  • 嗨 Pablo,我已经尝试过 flags = ["-c", "1"],然后尝试在 call() call([path, *flags, ip_addr]) 中解包,我收到语法错误。数组内不能解包吗?
  • @user1330734:它是 Python 3.5+ 语法。
  • @J.F. Sebastian 有趣的是,python 代码似乎是同步的,即每个 ping 调用似乎都在等待之前的完成。相比之下,我在上面添加的分叉 bash 脚本大约需要 5 秒才能完成 IP 范围 1-254。
  • @user1330734 阅读 subprocess.call(cmd). Think: what is the difference between subprocess.Popen(cmd)` 和 subprocess.Popen(cmd).wait()` 的文档,哪个更接近 @987654326 @.
  • @J.F.塞巴斯蒂安感谢您为我指出正确的地方。为了实现并发,我需要调用subprocess.Popen(cmd)。 subprocess.call(cmd) 似乎更接近 subprocess.Popen.wait()。 python 脚本现在按预期执行,干杯。
【解决方案2】:

正如@Pablo 提到的flagspath 变量应该是一个列表元素,所以在调用call 方法之前只需将您的命令字符串转换为列表:

path = "ping"
flags = "-c 1"
cmd_list = [path] # convert string to list
cmd_list = cmd_list + flags.split(' ') # converting your flags string to list elements

call(cmd_list)

【讨论】:

    猜你喜欢
    • 2015-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多