Проблема цитирования переменной сценария оболочки - PullRequest
1 голос
/ 14 января 2010

У меня есть скрипт sh, содержащий строку

$PHP_COMMAND -r 'echo get_include_path();'

Я не могу редактировать этот скрипт, но мне нужно, чтобы конечная командная строка была (эквивалентна)

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

Как мне этого добиться?


Ниже приведен скрипт, демонстрирующий проблему.

#!/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();'

Скрипт также доступен онлайн: http://gist.github.com/276500

Ответы [ 4 ]

3 голосов
/ 14 января 2010

Читая ваши комментарии к другим ответам, я попытался расшифровать то, что вы действительно хотели спросить:

У меня есть скрипт sh, содержащий строку

$PHP_COMMAND -r 'echo get_include_path();'

Я не могу редактировать этот скрипт, но мне нужно, чтобы конечная командная строка была (эквивалентна)

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

Как мне этого добиться?

Если это точно отражает вашу ситуацию, то это один из способов:

Напишите другой скрипт (я назову его /some/path/to/bar.sh) для использования в качестве PHP_COMMAND. Поскольку переменная не заключена в кавычки в исходном скрипте, вам необходимо убедиться, что полный путь к bar.sh не содержит специальных символов оболочки (например, пробелов).

/ некоторые / путь / к / bar.sh

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

Затем, чтобы запустить его, установите PHP_COMMAND и запустите оригинальный скрипт (/path/to/foo.sh):

env PHP_COMMAND=/some/path/to/bar.sh '/path/to/foo.sh'
2 голосов
/ 14 января 2010

Должен быть более простой способ, но одно из исправлений заключается в том, чтобы заключить всю командную строку в двойные кавычки, а затем вычислить следующее:

PHP_COMMAND="php -d 'include_path=/path/with spaces/dir'"
eval "$PHP_COMMAND -r 'echo get_include_path();'"
0 голосов
/ 14 января 2010

У Баша printf есть особая секретная магия, которая может помочь. Попробуйте:

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

или какой-то другой вариант.

Edit:

Извините, мне следовало включить некоторые объяснения и пример. Флаг %q заставляет printf добавить экранирование к строке, чтобы его можно было использовать в другой команде. Вывод этого printf будет выглядеть так (экранируются одинарные кавычки):

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

Эта команда иллюстрирует дополнительное экранирование:

$ printf "%q" "string ';\ text"
string\ \'\;\\\ text
0 голосов
/ 14 января 2010

что по этому поводу?

$PHP_COMMAND ' -r echo get_include_path();' 
...