Сбой сценария Bash при выполнении команды со встроенными кавычками (исходные параметры)

Я использую source для вставки сгенерированных переменных в строку из файла, чтобы выполнить эту строку из сценария bash.

Я повторил сгенерированную строку для сравнения с той, которая работает из командной строки, и я не вижу никакой разницы, но команда bash терпит неудачу, поскольку кажется, что предоставленные параметры смешиваются где-то посередине.

Я избежал двойных кавычек вокруг строки ice_name, поэтому она выглядит идентично той, которая работает, когда я повторяю ее.

Нужно ли экранировать других персонажей?

Кажется, что-то путают ДО параметра -ice_name

это команда

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://:[email protected]/my/mount/point/url

Не уверен, что вам нужен исходный файл, но на всякий случай вот он

#!/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

Скрипт, который обрабатывает файл конфигурации и генерирует команду потока

#!/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

person dbmitch    schedule 08.07.2016    source источник
comment
Какую команду вы используете для генерации команды после получения файла? Я подозреваю, что вы стали жертвой буквальных кавычек; echo "foo" и bar='"foo"'; echo $bar не идентичны.   -  person chepner    schedule 08.07.2016
comment
Просто используя $streamcmd - нет эха. Или вы хотите увидеть скрипт, который выполняет все слияния и конкатенации?   -  person dbmitch    schedule 08.07.2016
comment
Добавлен скрипт к исходному вопросу   -  person dbmitch    schedule 08.07.2016


Ответы (1)


Включение кавычек в строку не приводит к экранированию обернутых символов; они просто буквальные символы в значении. Для этого вам нужно использовать массивы:

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"
person chepner    schedule 08.07.2016
comment
Я попробую - в отдельном разговоре с вопросом об исходной команде мне сказали, что я могу просто запустить команду, выполнив одну переменную напрямую. Это выглядит радикально иначе. Я просто предположил, что это было правильно, когда это выглядело хорошо на экране - и ошибка указывала на то, что он пытался обработать команду, но не удалось выполнить параметры. - person dbmitch; 08.07.2016
comment
Гавдам! Гений!. Большое спасибо - жаль, что я не спросил раньше. Должно быть, провел 2 часа прошлой ночью снова и снова - person dbmitch; 09.07.2016
comment
Была ли основная проблема встроенными кавычками - или мне пришлось бы использовать этот метод, если бы у меня не было параметра с пробелами? Я думаю, что мне следует переименовать заголовок моего вопроса, чтобы более точно представить проблему. - person dbmitch; 09.07.2016
comment
В этом случае вам могло это сойти с рук; если расширенная команда не содержит специальных символов подстановки, таких как * или ?, содержит только пробелы, предназначенные для разделения аргументов, и не использует синтаксис оболочки, такой как |, > или &&, то расширение $test_cmd должно привести к допустимому < i>простая команда. Однако в целом переменная должна использоваться только для хранения данных, а не исполняемого кода. Для всего остального используйте массивы и функции оболочки. - person chepner; 09.07.2016
comment
Почти в каждом случае, когда я вижу, что кто-то пытается это сделать, это попытка сохранить команду в виде одной строки, чтобы ее можно было зарегистрировать. - person chepner; 09.07.2016
comment
Собираюсь задать еще один вопрос, который расширяет этот вопрос - повторная передача в avconv - будет ссылаться на этот - person dbmitch; 09.07.2016
comment
Не уверен, что вы являетесь экспертом как по sh, так и по bash - я только что опубликовал вопрос об этом коде, который дает сбой при использовании /bin/sh - ему не нравится строка stream_parameters=(-ice_name "$icecast_show" -f mp3), говорящая о синтаксической ошибке, - и сообщение проверки оболочки - In POSIX sh, arrays are undefined. Я думаю, что вынужден использовать sh, когда я вызываю скрипт через AT-команду. - person dbmitch; 14.07.2016
comment
stackoverflow .com/questions/38365845/ - person dbmitch; 14.07.2016