为什么 sed 不能在 PHP exec 命令中工作?

发布于 2024-12-25 02:00:36 字数 1525 浏览 1 评论 0原文

我有一个只能通过指定 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 中调用时不起作用?

I have a secure staging site accessible only via designated IP addresses. It needs to be able to switch apparent URLs to reflect the real site so I set up a simple form to allow the testers to switch between staging 'sites' by editing the .htaccess file on their behalf. The PHP command to edit the .htaccess file was set up thus:

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

A grep command run before and after invoking this command are run to check it thus:

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

The grep commands work fine and copy/pasting the sed line to the command line also works fine. However the sed command fails when run on the web page via the PHP exec command as above yielding an exit status of 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

The process has write access to the file and as I can't find a way to get any more information on the error I'm stumped.

I know I can work around the problem with a more complex solution using preg_replace but I would love to know why the above code does not work.

Can anyone tell me why sed is not working when invoked in exec the way I've set it up above?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

半透明的墙 2025-01-01 02:00:36

说明

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);

Explanation

sed creates a temporary working file when used with option -i. Then, sed uses the content of this temporary file to update in place the source file (e.g. ../.htaccess).

However, when sed cannot create this temporary file, it returns the exit value 4.
(sed creates this temporary file in the directory where the source file is located)

Therefore the directory where .htaccess is located may be write-protected or something like that (ACL...). I have never seen the error 'Array ( )': Let me know if you find...

Possible workarounds

Use your own temporary .htaccess.tmp file (i.e. do not use -i option):

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

You may use cp instead of cat but cat will preserve original owner and permission of .htaccess.

Another idea is to retrieve the sed output, then to write back the .htaccess file:

$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);
久夏青 2025-01-01 02:00:36

将您的 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>

Put your sed stuff within a script 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

Do not forget to give execution permission:

chmod +x /your/dir/set_MAGE_RUN_CODE.sh

Then update your PHP code:

<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>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文