Don
Don

Reputation: 4202

How to pass a bash variable to a php function without an undefined variable error message?

I am generating a password hash that I would like to base on user input for use later in the script. I have tried variations on the syntax for the bash variable in the following:

#!/bin/bash

printf "Enter password:"
read pw

php -r 'echo password_hash("$pw", PASSWORD_DEFAULT, [ "cost" => 11 ]) . "\n";'

I get the correct hash but only after I get an undefined variable warning.

When I put the variable in single quotes '$pw' and then input the password as "password" or 'password' I do not receive the error.

How can I pass a bash variable to a php command or otherwise assign it to a php variable within a bash script without the undefined variable error message?

Upvotes: 1

Views: 197

Answers (2)

dimo414
dimo414

Reputation: 48864

php -r 'echo password_hash("$pw", PASSWORD_DEFAULT, [ "cost" => 11 ]) . "\n";'

A single-quoted string in Bash does not do variable expansions, so you're literally passing the string $pw to PHP to parse, and since it doesn't exist you get a warning from PHP. The hash you get back is likely of the empty string, not the string you want. Try replacing php -r with echo in your script to see exactly what's being passed to php.

The suggestion to export the variable is a good option for security reasons (though you should use $_ENV, not $_SERVER), however in the general case (i.e. not a password) it's not necessary. Properly quoting the string so that the variable is evaluated in Bash is easy to do once you understand Bash's quoting semantics (which admittedly can be confusing).

For this case it should be sufficient to simply invert the single and double quotes in your string:

php -r "echo password_hash('$pw', PASSWORD_DEFAULT, [ 'cost' => 11 ]) . '\n';"

Upvotes: 1

Michael Jaros
Michael Jaros

Reputation: 4681

Passing variables via the environment is the way to go (because the password will never be accessible to more processes or users than necessary, in contrast to passing it via php's command line).

This should be done with the export builtin for POSIX compliance. Alternatively, the Bash-only declare -x can be used as well.

printf "Enter password:"
read pw

# export pw to the environment:
export pw

# the process executing your php program reads pw from the
# environment that it inherited from its parent process:
php -r 'echo password_hash($_SERVER["pw"], PASSWORD_DEFAULT, [ "cost" => 11 ]) . "\n";'

Note that the population of superglobal arrays depends on the value of variables_order in your PHP configuration (The S character must be in this setting's value to populate $_SERVER).

Upvotes: 2

Related Questions