为什么sed在PHP exec命令中不起作用?

时间:2012-01-03 01:05:26

标签: php sed exec

我有一个安全的临时站点,只能通过指定的IP地址访问。它需要能够切换明显的URL以反映真实的站点,因此我设置了一个简单的表单,允许测试人员通过代表他们编辑.htaccess文件在登台“站点”之间切换。编辑.htaccess文件的PHP命令如下:

$sed_cmd = "/bin/sed -i 's/^SetEnv MAGE_RUN_CODE=.*$/SetEnv MAGE_RUN_CODE=".$run_code."/' ../.htaccess";

运行调用此命令之前和之后运行的grep命令,以便检查它:

<p>Previous switch: <strong><em><?php echo `grep 'SetEnv MAGE_RUN_CODE=' ../.htaccess`; ?></strong></em></p>
      <?php exec($sed_cmd, $sed_out, $sed_result); ?>
      <p>Command <strong><em><?php echo $sed_cmd?></em></strong> yielded:
      <br />Return: <?php echo $sed_result; ?>
      <br />Printed:<strong><em><?php print_r($sed_out); ?></em></strong></p>
<p>New switch: <strong><em><?php echo `grep 'SetEnv MAGE_RUN_CODE=' ../.htaccess`; ?></strong></em></p>

grep命令工作正常,将sed行复制/粘贴到命令行也可以正常工作。但是,当通过上面的PHP exec命令在网页上运行时,sed命令失败,退出状态为4:

Previous switch: SetEnv MAGE_RUN_CODE=naturapet_website

Command /bin/sed -i 's/^SetEnv MAGE_RUN_CODE=.*$/SetEnv MAGE_RUN_CODE=animal_health_store_website/' ../.htaccess yielded:
Return: 4
Printed:Array ( )

New switch: SetEnv MAGE_RUN_CODE=naturapet_website

该进程具有对该文件的写访问权限,因为我无法找到有关错误的更多信息的方法。

我知道我可以使用preg_replace解决更复杂的解决方案,但我很想知道为什么上面的代码不起作用。

任何人都可以告诉我为什么sed在exec中以我在上面设置的方式调用时不起作用?

2 个答案:

答案 0 :(得分:1)

说明

sed与选项-i一起使用时会创建临时工作文件。然后,sed使用此临时文件的内容来更新到位源文件(例如../.htaccess)。

但是,当sed无法创建此临时文件时,它会返回退出值4
sed在源文件所在的目录中创建此临时文件

因此.htaccess所在的目录可能是写保护的或类似的(ACL ...)。我从未见过错误' Array()':如果您发现,请告诉我......

可能的解决方法

使用您自己的临时.htaccess.tmp文件(即请勿使用-i选项):

$sed_cmd = "/bin/sed 's/^SetEnv MAGE_RUN_CODE=.*$/SetEnv MAGE_RUN_CODE=".$run_code."/' ../.htaccess > ../.htaccess.tmp && cat ../.htaccess.tmp > ../.htaccess";

您可以使用cp代替cat,但cat会保留.htaccess的原始所有者和权限。

另一个想法是检索sed输出,然后回写.htaccess文件:

$sed_cmd = "/bin/sed 's/^SetEnv MAGE_RUN_CODE=.*$/SetEnv MAGE_RUN_CODE=".$run_code."/' ../.htaccess";
exec ($sed_cmd, $sed_out, $sed_result);
$file = fopen ('../.htaccess', 'w');
fwrite ($file, $sed_out);
fclose ($file);

答案 1 :(得分:0)

sed内容放入脚本set_MAGE_RUN_CODE.sh

#!/bin/bash
FILE=../.htaccess
if [ -f "$FILE" ]
then 
   sed -i 's/^SetEnv MAGE_RUN_CODE=.*$/SetEnv MAGE_RUN_CODE=$@/' "$FILE"
else
   # print error
   echo >&2 "$(basename $0): Cannot find file '$FILE' in directory '$(pwd)'"
fi

不要忘记给予执行权限:

chmod +x /your/dir/set_MAGE_RUN_CODE.sh

然后更新您的PHP代码:

<p>Previous switch: <strong><em>
    <?php echo `grep 'SetEnv MAGE_RUN_CODE=' ../.htaccess`; ?>
</strong></em></p>

<?php exec("/your/dir/set_MAGE_RUN_CODE.sh new_website", $sed_out, $sed_result); ?>

<p>Command <strong><em><?php echo $sed_cmd?></em></strong> yielded:
  <br />Return: <?php echo $sed_result; ?>
  <br />Printed:<strong><em><?php print_r($sed_out); ?>
</em></strong></p>

<p>New switch: <strong><em>
  <?php echo `grep 'SetEnv MAGE_RUN_CODE=' ../.htaccess`; ?>
</strong></em></p>