Bash script fails when running command with embedd

2019-06-09 18:17发布

问题:

I'm using source to insert generated variables into a string from a file in order to execute that string from a bash script.

I've echoed the generated string to compare to one that works from the command line and I can't seem to see any difference, but the bash command fails as it seems the supplied parameters are getting mixed up somewhere in the middle.

I've escaped double quotes around the ice_name string, so it looks identical to the one that works when I echo it

Do I need to escape other characters?

It seems to be getting mixed up BEFORE the -ice_name parameter

This is the command

avconv -re -i test.mp3 -c:a libmp3lame -content_type audio/mpeg -b:a 128k -legacy_icecast 1 
-ice_name "Raspi Test Stream of MP3" -f mp3 
icecast://:mypwd@icecast.servername.com/my/mount/point/url

Not sure if it you need the file beng sourced, but just in case here it is

#!/bin/bash
#
# stream.cfg
#
# WiFi Settings
#
wifi_name=mywifi
wifi_password=mywifipwd
#
# Icecast Server Settings
#
icecast_server=icecast.server.com
icecast_port=443
icecast_mount_url=/user/mountpt/url
icecast_show="RPi Demo Show - autostart"
icecast_description="Test of Stream from RPi USB Audio to Spreaker"
icecast_user=""
# Source password
icecast_password=sourcepwd
#
# avconv setting for Raspbian Jessie Lite
# may not need if you're using a self compiled ffmpeg version
#
icecast_legacy=1
#
# Stream Settings - probably not safer to go higher unless great internet connection
#
stream_bitrate=128k

Script that processes config file and generates stream command

#!/bin/bash
#
# autostart-settings.sh
#
# Load in config file settings

CONFIG_FILE=~/autostart/autostart-settings.cfg

# Check if file exists
echo "does file exist"
if [ ! -f "$CONFIG_FILE" ]; then
    echo "Config File: $(CONFIG_FILE) does not exist"
    exit 1
else
    # process settings
    echo "running source on $CONFIG_FILE"
    source "$CONFIG_FILE"
fi

start_cmd="avconv -re -i /home/pi/test.mp3 -c:a libmp3lame -content_type audio/mpeg -b:a $stream_bitrate -legacy_icecast $icecast_legacy"

stream_parameters="-ice_name \"$icecast_show\" -f mp3"

icecast_setup="icecast://$icecast_user:$icecast_password@$icecast_server:$icecast_port$icecast_mount_url"

test_cmd="$start_cmd $stream_parameters $icecast_setup"
echo "Testing command: $test_cmd"

# Run command
$test_cmd

回答1:

Embedding quotes in a string does not escape the wrapped characters; they are just literal characters in the value. You need to use arrays for this:

cmd=avconv
args=(-re -i /home/pi/test.mp3 -c:a libmp3lame -content_type audio/mpeg -b:a "$stream_bitrate" -legacy_icecast "$icecast_legacy")

stream_parameters=(-ice_name "$icecast_show" -f mp3)

icecast_setup="icecast://$icecast_user:$icecast_password@$icecast_server:$icecast_port$icecast_mount_url"

test_cmd="$start_cmd $stream_parameters $icecast_setup"
echo "Testing command: $cmd ${args} ${stream_parameters[@]} $icecast_setup"

# Run command
"$cmd" "${args[@]}" "${stream_parameters[@]}" "$icecast_setup"