0

I'm writing a python (2.7) script where I have to execute some shell commands which will send UDP packets to a remote VM. To execute the command, I'm using the subprocess lib and using both Popen and call methods.

The following code shows my 2 approaches to send a UDP packet. The problem is, neither of them (call or Popen) work (nor does os.system, for the matter). The command is interpreted as a single echo of the string "hello > /dev/udp/192.168.85.36/3000", as shown when I print the output from the 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)

The interesting thing is that when I execute the exact same command directly in a terminal, the UDP packet is received in the remote VM. The difference is that inside the program, the echo command is inside a loop, executing multiple times (which is the expected behaviour). Any ideas?

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
imll
  • 321
  • 3
  • 13

1 Answers1

3

There are two issues that prevent this from working:

  1. You are passing > and /dev/udp/.. to echo. Handling > is not echo's job. It's up to the shell. If you don't invoke a shell, it's your job.
  2. /dev/udp is not a real device/directory. Bash intercepts it and opens a socket instead. If you don't run bash (and note that shell=True and os.system will instead run sh), opening a socket is your job.

The easiest way to fix it without taking on that extra work is to invoke bash to do it:

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

The best way to fix it is to use Python's UDP functionality, see e.g. Python send UDP packet

that other guy
  • 116,971
  • 11
  • 170
  • 194