1

У меня есть сценарий, который принимает команды (для скрипта, а не для bash) в качестве аргументов.Bash metaprogramming

Он обрабатывает два заклинания ниже того же:

$ ./my_script -f 'cmd1','cmd2','cmd3' #etc 
$ ./my_script -f 'cnd1' -f 'cmd2' -f'cmd3' #etc 

Частым примером использования сценария имели бы он взять команды одного и того же семейства, но с разными аргументами или флагов:

$ ./my_script -f 'cmd arg1','cmd arg2','cmd arg3' 

Я хотел бы иметь возможность напечатать это в сжатом виде, по существу, как декартово произведение {"'cmd "}{arg1,arg2,arg3,...}, за которым следует «'» `

Я знаю Баш может сделать декартовы продукты, и в самом деле:

$ echo "-f 'cmd "{arg1,arg2,arg3}"'" 

выводит вторую часть моего вызова во второй форме:

-f 'cmd arg1' -f 'cmd arg2' -f 'cmd arg3' 

Однако, если используется в вызове, как это:

$ ./my_script "-f 'cmd "{1,2,3}"'" 

сценарий, конечно, рассматривает его как 3 аргумента с пробелами в них. Если я эхо декартово часть продукта в субоболочке следующим образом:

$ ./my_script $(echo "-f 'cmd "{1,2,3}"'") 

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

с помощью рубинового Однострочник, чтобы проиллюстрировать, как скрипт получает Params в каждом конкретном случае:

$ ruby -e 'puts ARGV.each_with_index.map {|a,i| (i+1).to_s+" : "+a}' -- "-f 'cmd "{1,2,3}"'" 
1 : -f 'cmd 1' 
2 : -f 'cmd 2' 
3 : -f 'cmd 3' 

$ ruby -e 'puts ARGV.each_with_index.map {|a,i| (i+1).to_s+" : "+a}' -- $(echo "-f 'cmd "{1,2,3}"'")                                
1 : -f 
2 : 'cmd 
3 : 1' 
4 : -f 
5 : 'cmd 
6 : 2' 
7 : -f 
8 : 'cmd 
9 : 3' 

Так что мой вопрос, могу ли я получить Баш оценить вывод команды echo, как если бы это было введенный пользователем? (процесс кавычки и все?)

Update:

Я должен отметить, что скрипт принимает другие Params, которые могут иметь пробелы в них, так что на самом деле я искал какой-то частичное , локализованный eval (если есть такая вещь), так как в противном случае мне пришлось бы избежать других кавычек, чтобы они прошли до eval.

(Если нет, я просто добавлю способность картотеки к скрипту, но я чувствовал себя уверенным, что нет изящного способа сделать это извне.)

+3

Для quasiquoting в bash land, 'printf '% q" 'является обязательным для чтения в man-странице – sehe

ответ

3

Вот где вам нужен дополнительный шаг eval:

Это напоминает ваш рубиновый скрипт (без подсчета):

f() { 
    for arg 
    do 
    echo "[$arg]" 
    done 
} 

И это, как вы тогда называете это:

eval f "-f 'cmd "{1,2,3}"'" 

Ожидаемые результаты:

[-f] 
[cmd 1] 
[-f] 
[cmd 2] 
[-f] 
[cmd 3]