Ошибка сценария Perl Drush Command
Я пытаюсь добавить фрагмент кода php в узел веб-формы Drupal. Я получаю сообщение об ошибке синтаксиса сообщения рядом с неожиданным токеном `(', который появляется в строке под комментарием к Drupal Query. Любая помощь? Я избежал паренов и знаков доллара.
#!/usr/bin/perl
use strict;
my $updatesdir = '/var/www/html/mysite/releaseupdates/spint1';
my $drupalroot = '/var/www/html/mysite/web';
my $drushcmd = '/usr/bin/drush';
# Drupal Query
system("$drushcmd -r $drupalroot -u sites.admin --yes sql-query 'update node_revisions set body = REPLACE\(body,\'</div>\',\'<?php \$contact_us_node = abc_drupal_node_load\(NULL, \'my_group\'\);if \(isset\(\$contact_us_node->field_contact_us_message_body\)\) {echo \$contact_us_node->field_contact_us_message_body[0][\'value\'] . \"<br />\";}?></div>\'\) WHERE nid=123'") == 0 or die "$drushcmd failed: $?";
print "Contact Us Body Text updated with PHP Code.\n";
1 ответ
Вы передаете эту строку system
и, следовательно, ваша оболочка (отформатированная для лучшей читабельности):
/usr/bin/drush
-r /var/www/html/mysite/web
-u sites.admin
--yes sql-query '
update node_revisions
set body = REPLACE(body,'</div>',
'<?php
$contact_us_node = abc_drupal_node_load(NULL, 'my_group');
if (isset($contact_us_node->field_contact_us_message_body)) {
echo $contact_us_node->field_contact_us_message_body[0]['value'] . "<br />";
}
?></div>'
)
WHERE nid=123'
Зачем? Строки Perl в двойных кавычках игнорируют неизвестные экранированные символы, удаляя обратную косую черту. Например: "\(" eq "("
, Это означает, что когда оболочка видит эту команду, все эти обратные слеши отсутствуют! Давайте посмотрим, какие "строки" на самом деле видит оболочка:
/usr/bin/drush
-r
/var/www/html/mysite/web
-u
sites.admin
--yes
sql-query
'update node_revisions set body = REPLACE(body,'
</div>
','
<?php $contact_us_node = abc_drupal_node_load(NULL,
'my_group'
);if (isset($contact_us_node->field_contact_us_message_body)) {echo $contact_us_node->field_contact_us_message_body[0][
'value'
] .
"<br />"
;}?></div>
') WHERE nid=123'
Это абсолютно не то, что вы хотели. У нас есть три уровня побега:
- Строка Perl
- Оболочка
- SQL
- (PHP-код, но здесь он не использует никаких выходов)
Как мы можем решить это? Мы можем удалить уровень оболочки, имея Perl exec
команда напрямую, не передавая ее в оболочку. Для этого мы используем форму списка этой команды:
system(
$drushcmd,
'-r', $drupalroot,
'-u', 'sites.admin',
'--yes',
'sql-query',
"update node_revisions set body = REPLACE\(body,\'</div>\',\'<?php \$contact_us_node = abc_drupal_node_load\(NULL, \'my_group\'\);if \(isset\(\$contact_us_node->field_contact_us_message_body\)\) {echo \$contact_us_node->field_contact_us_message_body[0][\'value\'] . \"<br />\";}?></div>\'\) WHERE nid=123'",
) == 0 or die "$drushcmd failed: $?";
Ах да, это лучше. Мы можем дополнительно исключить необходимость экранирования внутри кода Perl, используя строки в одинарных кавычках с альтернативным разделителем:
q#update node_revisions set body = REPLACE(body,'</div>','<?php $contact_us_node = abc_drupal_node_load(NULL, 'my_group');if (isset($contact_us_node->field_contact_us_message_body)) {echo $contact_us_node->field_contact_us_message_body[0]['value'] . "<br />";}?></div>') WHERE nid=123'#
Теперь мы удалили экранирующие уровни для Perl и оболочки, поэтому остался только SQL.