Perl Drush Command脚本错误

时间:2014-03-24 21:10:08

标签: perl drupal-6 drush

我试图将php代码段添加到Drupal Web表单节点中。我在意外令牌附近收到错误消息语法错误`('发生在Drupal Query评论下面的行上。有什么帮助吗?我逃脱了parens和美元符号。

#!/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 个答案:

答案 0 :(得分:1)

您将此字符串传递给system,从而传递给您的shell(为了更好的可读性而格式化):

/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 "("。这意味着当shell看到该命令时,所有这些反斜杠都会丢失!让我们看一下shell实际看到的“字符串”:

/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'

这绝对不是你想要的。我们有三个级别的转义

  1. Perl字符串
  2. 外壳
  3. SQL
  4. (PHP代码,但它并没有在这里使用任何转义)
  5. 我们如何解决这个问题?我们可以直接使用Perl exec命令删除shell级别,而不将其传递给shell。为此,我们使用该命令的列表形式:

    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和shell的转义级别,所以只剩下SQL。