2015-04-27 4 views
2

Рассмотрим этот Makefile:безопасно передать сделать переменную команды оболочки

VAR1=oneword 
VAR2=two words 
VAR3=three" quoted "words 

test: 
    printf '>%s< ' "$(VAR1)" "$(VAR2)" "$(VAR3)" 
    @echo 

Если я запускаю его, я получаю

$ make test 
printf '>%s< ' "oneword" "two words" "three" quoted "words" 
>oneword< >two words< >three< >quoted< >words< print 

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

$ printf '>%s< ' "oneword" "two words" "three\" quoted \"words" 
>oneword< >two words< >three" quoted "words< 

Предположим, я не могу изменить переменные, то есть я должен изменить вызов printf каким-то образом ,

Другими словами: Как передать содержимое переменной Make в команду оболочки в качестве одного параметра без какого-либо разделения на несколько или каких-либо конкретных эффектов оболочки?

ответ

2

Make поддерживает export директиву передать буквальное содержание в окружающей среде:

VAR1=oneword 
VAR2=two words 
VAR3=three" quoted "words 

export VAR1 
export VAR2 
export VAR3 

test: 
     printf '>%s< ' "$$VAR1" "$$VAR2" "$$VAR3" 
     echo 

Выход:

$ make test 
printf '>%s< ' "$VAR1" "$VAR2" "$VAR3" 
>oneword< >two words< >three" quoted "words< echo 
+0

Спасибо, я забыл про 'export'. Это может быть хорошей альтернативой, если вы не возражаете загромождать окружающую среду. –

+0

* кив *. Честно говоря, я предпочитаю этот подход в основном по идеологическим соображениям - передача данных вне диапазона из кода полностью исключает любой потенциал для экранов - хотя для оболочки, совместимой с POSIX, ваш ответ должен быть полностью адекватным. (Я склонен немного нахмуриться в части «дезинфекции ваших входов» части Bobby Tables XKCD по тем же причинам: хорошая реализация параметров привязки приведет к тому, что данные будут полностью вне диапазона от кода, что делает ненужным дезинфекцию). –

+0

... конечно, «полностью» предполагает, что нет данных о том, что данные снова становятся кодовыми, a la Shellshock, но это совсем другое обсуждение. –

1

Я нашел решение. Это не здорово для читаемости, но кажется очень надежным.

Идея состоит в том, чтобы использовать одинарные кавычки на уровне оболочки ('), так как там нет переменной интерполяции или других странных вещей. Кроме того, это означает, что единственный персонаж, который нам нужно беспокоиться о в содержимом переменных являются одинарными кавычками, и они могут быть заменены надежно:

VAR1=oneword 
VAR2=two words 
VAR3=three" quoted 'words 

test: 
    printf '>%s< ' '$(subst ','\\'',$(VAR1))' '$(subst ','\\'',$(VAR2))' '$(subst ','\'',$(VAR3))' 
    @echo 

И теперь я получаю

$ make test 
printf '>%s< ' 'oneword' 'two words' 'three" quoted '\''words' 
>oneword< >two words< >three" quoted 'words< 

Примечания как make правильно экранировал ', и как команда оболочки получает его надежно.

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