Question

I have an sh script that contains the line

$PHP_COMMAND -r 'echo get_include_path();'

I can not edit this script, but I need the eventual command line to be (equivalent to)

php -d include_path='/path/with spaces/dir' -r 'echo get_include_path();'

How can I achieve this?


Below is a script that demonstrates the problem.

#!/bin/sh

# shell script quoting problem demonstration

# I need to be able to set a shell variable with a command with 
# some options, like so
PHP_COMMAND="php -d 'include_path=/path/with spaces/dir'"
# then use PHP_COMMAND to run something in another script, like this:
$PHP_COMMAND -r 'echo get_include_path();'
# the above fails when executed. However, if you copy/paste the output
# from this line and run it in the CLI, it works!
echo "$PHP_COMMAND -r 'echo get_include_path();'"
php -d include_path='/path/with spaces/dir' -r 'echo get_include_path();'
# what's going on?

# this is also interesting
echo "\n--------------------"

# this works great, but only works if include_path doesn't need quoting
PHP_COMMAND="php -d include_path=/path/to/dir"
echo "$PHP_COMMAND -r 'echo get_include_path();'"
$PHP_COMMAND -r 'echo get_include_path();'

echo "\n--------------------"

# this one doesn't when run in the sh script, but again if you copy/paste 
# the output it does work as expected.
PHP_COMMAND="php -d 'include_path=/path/to/dir'"
echo "$PHP_COMMAND -r 'echo get_include_path();'"
$PHP_COMMAND -r 'echo get_include_path();'

Script also available online: http://gist.github.com/276500

Was it helpful?

Solution

There should be a simpler way, but one fix is to surround the entire command line with double quotes and then eval that:

PHP_COMMAND="php -d 'include_path=/path/with spaces/dir'"
eval "$PHP_COMMAND -r 'echo get_include_path();'"

OTHER TIPS

Reading your comments on other answers, I have tried to decipher what you really intended to ask:

I have an sh script that contains the line

$PHP_COMMAND -r 'echo get_include_path();'

I can not edit this script, but I need the eventual command line to be (equivalent to)

php -d include_path='/path/with spaces/dir' -r 'echo get_include_path();'

How can I achieve this?

If this accurately reflects your situation, then this is one way:

Write another script (I'll call it /some/path/to/bar.sh) to use as PHP_COMMAND. Since the variable is not quoted in the original script, you will have to make sure that the full pathname of bar.sh does not have any shell-special characters (like spaces).

/some/path/to/bar.sh

#!/bin/sh
exec php -d 'include_path=/path/with spaces/dir' ${1+"$@"}

Then, to run it, set PHP_COMMAND, and run the original script (/path/to/foo.sh):

env PHP_COMMAND=/some/path/to/bar.sh '/path/to/foo.sh'

Bash's printf has some special secret magic that might help. Try:

PHP_COMMAND="php -d $(printf "%q" "'include_path=/path/to/dir'")"

or some variation of that.

Edit:

I'm sorry, I should have included some explanation and an example. The %q flag causes printf to add escaping to the string so it can be reused in another command. The output of that printf would look like this (the single quotes get escaped):

\'include_path=/path/to/dir\'

This command illustrates some additional escaping:

$ printf "%q" "string ';\ text"
string\ \'\;\\\ text

what about this?

$PHP_COMMAND ' -r echo get_include_path();' 
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top