为什么不能从subprocess.Popen()或os.system()回显> / dev / udp / ...?

时间:2019-07-04 23:27:54

标签: python python-2.7 shell subprocess

我正在编写python(2.7)脚本,在其中必须执行一些shell命令,这些命令会将UDP数据包发送到远程VM。为了执行命令,我使用了子进程lib,同时使用了Popen和call方法。

以下代码显示了我的两种发送UDP数据包的方法。问题是,它们(调用或Popen)都不起作用(对此,os.system也不起作用)。该命令被解释为字符串“ hello> /dev/udp/192.168.85.36/3000”的单个回显,如我从PIPE打印输出所示。

myCmd = 'echo hello > /dev/udp/192.168.85.36/3000'

subprocess.call(myCmd, shell=True)

subprocess.Popen(myCmd.split(), stderr=subprocess.PIPE,\ 
                 stdout=subprocess.PIPE)

subprocess.Popen(['echo', 'packet', '>','/dev/udp/192.168.85.36/3000'],\
                  shell=False, stderr=subprocess.PIPE,stdout=subprocess.PIPE)

有趣的是,当我直接在终端中执行完全相同的命令时,远程VM会收到UDP数据包。区别在于,在程序内部,echo命令在循环内部,执行多次(这是预期的行为)。有什么想法吗?

1 个答案:

答案 0 :(得分:3)

有两个问题阻止了此工作:

  1. 您正在将>/dev/udp/..传递到echo。处理>不是echo的工作。这取决于外壳。如果您不调用Shell,它就是您的 工作。
  2. /dev/udp不是真实的设备/目录。 Bash拦截了它并打开了一个套接字。如果您不运行bash(请注意,shell=Trueos.system会运行sh),则打开套接字是您的工作。

最简单的解决方法而不进行额外的工作就是调用bash来完成它:

subprocess.Popen(['bash', '-c', 'echo packet > /dev/udp/192.168.85.36/3000'], shell=False, stderr=subprocess.PIPE, stdout=subprocess.PIPE)

修复此问题的最佳方法是使用Python的UDP功能,请参见例如Python send UDP packet