Search code examples
shellmakefileescapingquoting

Safely pass Make variable to shell commands


Consider this Makefile:

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

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

If I run it, I get

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

but I would like to get the same result as if I ran the following command:

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

Assume I cannot change the variables, i.e. I have to change the call to printf somehow.

In other words: How do I pass the content of a Make variable to a shell command as one parameter, without any splitting into several or any specific shell effects occurring?


Solution

  • Make supports the export directive to pass literal content through the environment:

    VAR1=oneword
    VAR2=two words
    VAR3=three" quoted "words
    
    export VAR1
    export VAR2
    export VAR3
    
    test:
            printf '>%s< ' "$$VAR1" "$$VAR2" "$$VAR3"
            echo
    

    Output:

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