views:

91

answers:

4

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

A: 

what about this?

$PHP_COMMAND ' -r echo get_include_path();' 
darren
that doesn't execute.
apinstein
+1  A: 

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();'"
R Samuel Klatchko
ok wow cool! that's a good start.It's a solution, but it's not an answer to my question (which I think you realize).Since the script that runs the command is a third-party script, I'd like a solution that doesn't require munging the third-party script.But thanks, this is at least a workable solution.
apinstein
A: 

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
Dennis Williamson
i am not sure how this helps my problem... the problem occurs when substituted into the final command, not in preparing the "PHP_COMMAND" variable. Could you do a 2-line working example?
apinstein
Thanks for the edit. I tried it, but it didn't work. I am still getting the same error. If you could provide a working copy/paste example based on my example that'd be great. Although, you should know I think the 'eval' solution so far seems the simplest so far.
apinstein
+1  A: 

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'
Chris Johnsen
You elegantly re-phrased my question. My examples reflected this, but I guess my copy was less precise. I'll see if they let me edit my post.Your solution is a very interesting idea, that's quite clever. I will try that out later.
apinstein