1

I have this bash script I want to call directly from Python:

#!/bin/bash  
for usb in $(ls /dev/ttyUSB*); do echo $(udevadm info $usb | grep ID_SERIAL= | cut -d ' ' -f 2) $usb; done

I'm getting error on the very first section:

from subprocess import Popen
Popen('ls /dev/ttyUSB*'.split())

I understand that this is due to Popen running sh, and it does not support wildcard, so I tried invoking bash with:

from subprocess import Popen
Popen('/bin/bash ls /dev/ttyUSB*'.split())

OR

Popen('/bin/bash "ls /dev/ttyUSB*"'.split())

but got

/bin/ls: /bin/ls: cannot execute binary file

However, the files do exist:

ls /dev/ttyUSB*

outputs: /dev/ttyUSB0 /dev/ttyUSB1 /dev/ttyUSB2 /dev/ttyUSB3

After solving this, I still have to understand how can I use a pipe in the middle of () [i.e. - for usb in $(ls /dev/ttyUSB*); do echo $(udevadm info $usb | grep

Poshi
  • 5,332
  • 3
  • 15
  • 32
CIsForCookies
  • 12,097
  • 11
  • 59
  • 124
  • Can you please clarify what your problem is? You are *not* calling the bash script, you have copied the command from the script. ``sh`` *does* support wildcards/globs - ``Popen`` does *not* run ``sh``, which is why globs do not work. Python *has* the ``glob`` module for that - which completely eliminates the need for calling ``ls`` and piping its output. So, do you want to a) *port* the functionality from bash to Python or b) *call* bash from Python? – MisterMiyagi Feb 26 '19 at 09:10
  • I want to port the funcnioality, and thought of `glob` but I still need the `udevadm info` call from shell, so calling the script directly seems easier – CIsForCookies Feb 26 '19 at 09:11
  • 2
    In that case, just paste the command verbatim and set ``shell=True``. For example, ``subprocess.run("ls . | grep '\.py'", shell=True)``. – MisterMiyagi Feb 26 '19 at 09:15
  • change 'run' to 'call' and post as an answer, if you'd like – CIsForCookies Feb 26 '19 at 09:17
  • You have multiple misunderstandings here, but most obviously you want `bash -c "commands; some more commands"` or `sh -c "commands; some more commands"` rather than without `-c`. Also don't use `Popen()` for stuff which `call()` or `ruin()` will do reliably, transparently, and easily. – tripleee Feb 26 '19 at 12:24
  • My answer to the second duplicate has a long list of gotchas, several of which seem pertinent here. – tripleee Feb 26 '19 at 12:24
  • `for node in glob.glob('/dev/ttyUSB*'): output = subprocess.check_output(['udevadm', 'info', node]); for line in output.split('\n'): if 'ID_SERIAL=' in output: print(output.split(' ')[1])` – tripleee Feb 26 '19 at 13:06

0 Answers0