2013-12-06 2 views
4

Я повторил этот пример, чтобы сохранить его простым, но то, что я пытаюсь сделать, это получить вложенную строку двойной кавычки как одно значение argv, когда оболочка bash выполняет ее.Передача Bash и Double-Quotes в argv

Вот пример сценария:

set -x 
command1="key1=value1 \"key2=value2 key3=value3\"" 
command2="keyA=valueA keyB=valueB keyC=valueC" 
echo $command1 
echo $command2 

выход:

++ command1='key1=value1 "key2=value2 key3=value3"' 
++ command2='keyA=valueA keyB=valueB keyC=valueC' 
++ echo key1=value1 '"key2=value2' 'key3=value3"' 
key1=value1 "key2=value2 key3=value3" 
++ echo keyA=valueA keyB=valueB keyC=valueC 
keyA=valueA keyB=valueB keyC=valueC 

Я сделал тест, а также, что, когда вы делаете все, что в командной строке, котировка сообщение вложенная устанавливается как одно значение argv. т.е.

prog.exe argument1 "argument2 argument3" 

argv[0] = prog.exe 
argv[1] = argument1 
argv[2] = argument2 argument3 

Используя приведенный выше пример:

command1="key1=value1 \"key2=value2 key3=value3\"" 

ошибка, мой ARGV является пришедшим обратно, как:

arg[1] = echo 
arg[2] = key1=value1 
arg[3] = "key2=value2 
arg[4] = key3=value3" 

, где я действительно хочу, чтобы мой ARGV [3] значение «ключ2 = значение2 ключ3 = значение3»

Я заметил, что debug (set -x) показывает одиночную кавычку в точках, где мои аргументы разбиваются, что своего рода указывает на то, что он думает об аргументах в этой точке останова ... просто не уверен.

Любая идея, что на самом деле происходит здесь? Как изменить сценарий?

Заранее спасибо.

ответ

4

Что происходит, так это то, что ваши вложенные кавычки являются буквальными и не разбираются в отдельные аргументы оболочки. Лучший способ справиться с этой помощью bash это использовать массив вместо строки:

args=('key1=value1', 'key2=value2 key3=value3') 
prog.exe "${args[@]}" 

Bash FAQ50 имеет еще несколько примеров и вариантов использования динамических команд.

+0

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

+0

Только проблема в том, что массивы не могут быть экспортированы ... –

1

Своего рода сумасшедшие «ответ», чтобы установить IFS в двойные кавычки, как это (сохранение/восстановление исходной СИФ):

SAVED_IFS=$IFS 
IFS=$'\"' 
prog.exe $command1 

IFS=$SAVED_IFS 

Это отчасти иллюстрирует слово расщепление, которое происходит на некотируемым аргументов, но не влияет на переменные или текст внутри ".." цитаты. Текст внутри двойных кавычек (после различных расширений) передается программе как один аргумент. Однако голой переменной $ command1 (без кавычек) подвергается разбиение слов, которое не заботится о " внутри переменной (беря ее буквально). Глупый взлом IFS заставляет разбивать слова на ". Также остерегайтесь конечного пробела в конце argv [1], который появляется из-за разбиения слова на границе ".

Ответ на jordanm намного лучше для использования в производстве, чем у меня :) Массив цитируется, то есть каждый элемент массива расширяется как отдельная строка, и после этого словосочетание не происходит. Это важно. Если он не определен как ${args[@]}, он будет разбит на три аргумента вместо двух.

Смежные вопросы