shellgomakefileargumentspasswords

How to pass '$' => Special Character as argument for makefile


I tried to pass password for postgres that is used in go scrip which is passed throug a makefile My password contains '$' character=> the makefile doesnt recognize it a character. I tried using escape character '$$' => this doesn't work too

pwsd:=$1

run:
    @echo "Password passed: ${pwsd}"
    @go run ./cmd/web ${pwsd}
input:
make run pwsd="passwd$"
output:
Password passed: passwd

input:
make run pwsd="passwd$$"
output:
Password passed: passwdpwsd=passwd$
expected:
Password passed: passwd$

Solution

  • First, when debugging makefiles you should never add the @ prefix to your recipe. This is like running your compiler with the output sent to /dev/null.

    You have to first understand that $ is special to the shell: it introduces a shell variable. So you have to escape the $ from the shell first of all. Using double-quotes doesn't do that: shell variables are expanded inside double-quotes:

    foo=bar
    echo "$foo"
    

    shows bar, not $foo. If you want to ensure that a string containing $ is not expanded by the shell, you should use single quotes:

    foo=bar
    echo '$foo'
    

    This will show $foo. So if you want the shell to see a string containing a dollar sign you need to both (a) invoke make with the value properly quoted, and (b) use proper escaping quotes in your recipe. For example:

    run:
            @echo 'Password passed: ${pwsd}'
            go run ./cmd/web '${pwsd}'
    

    Then if you run make pwsd='foo$bar' the result will be:

    Password passed: foo$bar
    go run ./cmd/web 'foo$bar'
    

    I should point out this will fail if your password can contain single-quotes. If you want to support this, you'll have to be extra-fancy; something like this:

    quoted_pwsd = '$(subst ','"'"',$(pwsd))'
    run:
            @echo Password passed: ${quoted_pwsd}
            go run ./cmd/web ${quoted_pwsd}
    

    but you have to be careful where you use this.