2013-08-04 3 views
4

Я хочу назвать dialog а-ля:Как разрешить пустые аргументы в командных подстановках?

dialog --menu Choose: 0 40 10 A '' B '' C '' 

кроме A, B и C являются результатом динамического запроса, ради этого вопроса последний будучи { echo A; echo B; echo C; }.

я могу получить нужную командную строку, казалось бы, с помощью:

{ echo A; echo B; echo C; } | sed -e "s/\$/ ''/;" 

но:

echo $({ echo A; echo B; echo C; } | sed -e "s/\$/ ''/;") 

и его выход:

A '' B '' C '' 

показать, что результат подстановки команд только word-split, но '' не интерпретируется как пустой аргумент, но передается до echo (и, таким образом, dialog не будет отображать описания для пунктов меню, но буквально '' s).

Я могу обойти это в bash с помощью массивов, но есть ли более простое решение, которое мне не хватает?

Учитывая

$ e() { printf "tag: [$1] item: [$2]"; } 
$ e $(echo "A ''") 
$ tag: [A] item: [''] 

Как я могу изменить $(...) часть, таким образом, что элемент [] вместо [''].

+0

Что реально проблема, которую вы пытаетесь решить? –

+0

@AnsgarWiechers Учитывая '{echo A; эхо B; echo C; } ', Я хочу выполнить' dialog - menu Выберите: 0 40 10 A '' B '' C '' '. –

+0

* Почему вы хотите запустить это? Чего вы хотите добиться, выполняя это? –

ответ

1

Вы можете изменить (разделитель внутреннего поля) IFS

$ IFS=, e $(echo "a,,") 
tag: [a] item: [] 

Кажется, работает. Это мило? Я не знаю, но давал бы магию массива. Кстати, вы можете часто использовать ${parameter/pattern/string} для замещения вместо вызова sed. К сожалению, он работает только с переменной, что делает ее менее полезной.

+0

Работал для меня, спасибо. Однако для вызова 'dialog' мне пришлось установить' IFS' в отдельной команде ('IFS =, dialog' не работал). Я закончил с: 'SAVEIFS =" $ IFS "; IFS = ,; если ! dialog --menu 'Выберите моментальный снимок для монтирования' 0 40 10 $ (sort .snaplist | sed -e 's/$/,, /;' | tr -d \\ n); затем [...] ' –

0

Вы можете попробовать это:

cmd="dialog --menu Choose: 0 40 10 " 
arg="`echo $({ echo A; echo B; echo C; } | sed -e "s/\$/ ''/;")`" 
eval "${cmd}${arg}" 

Но я думаю, что sed здесь не требуется. Вы можете держать его просто:

cmd="dialog --menu Choose: 0 40 10 " 
arg="`echo A \'\' B \'\' C \'\'`" 
eval "${cmd}${arg}" 
+0

Если бы мне не понадобилось 'sed', у меня не было бы проблемы :-). Проблема в том, что 'A',' B' и 'C' исходят из динамического запроса. –

+0

Да, но вы можете легко писать 'A',' B' и 'C' в строку' arg', используя подстановку команд. –

2

Хороший вопрос.

Я не знаю, если это квалифицируется как «проще», но она имеет определенную элегантность:

with-tags() { 
    local line 
    if read -r line; then with-tags "[email protected]" "$line" ""; else "[email protected]"; fi 
} 

{ echo A; echo B; echo C; } | 
with-tags dialog --menu Choose: 0 40 10 

Это легко расширяемой для обработки входных линий вида TAG <optional description>:

with-tag-lines() { 
    local tag desc 
    if read -r tag desc; then with-tag-lines "[email protected]" "$tag" "$desc"; else "[email protected]"; fi 
} 

{ echo A with optional description; echo B; echo C; } | 
with-tag-lines dialog --menu Choose: 0 40 10 
Смежные вопросы