0

I'm sure I'm missing something simple and stupid, but I'm trying to conditionally build a shell script line to launch mjpg_streamer based on which of multiple cameras are plugged in. The finished command runs when I copy/paste the stuff echoed, but something in my syntax is wrong in trying to actually run it in the script and I think the single quotes are dropping out. I'm not sure the correct bash syntax to make it work:

#!/bin/bash

streamer="mjpg_streamer"
wwwpath="/usr/local/share/mjpg-streamer/www"
httpopts="-n -w $wwwpath"
streamout="-o 'output_http.so $httpopts'"
raspicam=''
rcopts='-fps 10'
usbcam=''
usbopts='-r 640x480 -f 10'


### detect if raspicam is connected
output=$(vcgencmd get_camera)
if [[ ${output} == *"supported=1"* && ${output} == *"detected=1"* ]];then
    echo "raspicam found!"
    raspicam="-i 'input_raspicam.so $rcopts'"
fi

# look for a particular USB device id for the webcam
deviceid="046d:0804" # replace with camera device id
if [[ $( lsusb | grep -c "$deviceid") -ne 0 ]];then
    device=$(v4l2-ctl --list-devices | grep -A1 "$deviceid" | tail -1 | xargs)
    echo "Logitech USB camera found on: $device!"
    usbcam="-i 'input_uvc.so -d $device $usbopts'"
fi

if [[ $raspicam != '' || $usbcam != '' ]]; then
  echo ${streamer} ${streamout} ${raspicam} ${usbcam}
  ${streamer} ${streamout} ${raspicam} ${usbcam}
else
  echo "no cameras found!"
fi

executing this outputs:

mjpg_streamer -o 'output_http.so -n -w /usr/local/share/mjpg-streamer/www' -i 'input_raspicam.so -fps 10' -i 'input_uvc.so -d /dev/video0 -r 640x480 -f 10'
mjpg_streamer: invalid option -- 'n'
## extra stuff deleted ##

copy/pasting the first line as echoed will run successfully. I'm not sure how to execute the result without the single quotes being ignored.

Scott
  • 7,983
  • 2
  • 26
  • 41
  • 1
    Storing quotes in variables doesn't work, because the shell parses quotes before it expands variables. Build the command as an array, rather than a plain variable. See ["Why does shell ignore quoting characters in arguments passed to it through variables?"](https://stackoverflow.com/questions/12136948/) and [BashFAQ #50: "I'm trying to put a command in a variable, but the complex cases always fail!"](http://mywiki.wooledge.org/BashFAQ/050) (and ignore all suggestions involving `eval` -- it's a massive bug magnet). – Gordon Davisson Feb 25 '22 at 18:19
  • gotcha. I was hoping to get it all into one command line, but in the meantime (while waiting for a response) I wrote a modified version guessing it might be something like that which has 3 elif cases for both, one or the other cameras. So it still will run a single mjpg_streamer, but has to have 3 cases – Scott Feb 27 '22 at 01:25
  • (I was hoping there was some other way as I may add more cameras later and it's going to get unweildy!) – Scott Feb 27 '22 at 01:26
  • 1
    You can totally built it, just use an array (one element = one argument) instead of plain text variables; BashFAQ #50 has a section on this. Something like `cameras=(); if whatever; then cameras+=(-i "input_raspicam.so $rcopts"); ...` then use `"${cameras[@]}"`to expand those arguments in the final command. – Gordon Davisson Feb 27 '22 at 01:52
  • thanks, i'll try that if i go to three on one machine. For now, the server software I was going to use failed to meet expectations so I'm back to one machine per 3d printer. – Scott Feb 28 '22 at 02:40

0 Answers0