外壳在php-heredoc中



我在php脚本中有类似的东西:

<?php
...
function log() {
    // saving the log into a file.
    exec(<<<BASH
cat >> $logFile <<EOF
$log
EOF
BASH
    );
}
...

正如你所看到的,两个heredocs(BASH是php,EOF是shell)的结尾是人们认为正确的,但当我阅读创建的日志时,日志有这样的内容:

...
my logged string of an important event
EOF
my logged string of another important event
EOF
...

我检查了apache日志,它有以下条目:

sh: line 1: warning: here-document at line 0 delimited by end-of-file (wanted `EOF')

我做错了什么?

请注意,我知道还有许多其他实现,例如使用php函数或使用引号代替heredocs。但我很好奇,为什么在这种特殊情况下,这不起作用。

编辑。我澄清了代码,这样我说的php运行shell命令就更清楚了。

PHP案例的更新答案

假设我们有test.php文件,其中包含以下内容:

<?php
function mylog() {
  $logFile = 'test.log';
  $log = 'test';
  exec(<<<BASH
cat >> $logFile <<EOF
$log
EOF
BASH
     );
}
mylog();

然后php test.php产生正确的东西(!):

rm -f test.log
php test.php
cat test.log

输出:

test

现在让我们缩进Bash部分:

<?php
function mylog() {
  $logFile = 'test.log';
  $log = 'test';
  exec(<<<BASH
  cat >> $logFile <<EOF
  $log
  EOF
BASH
     );
}
mylog();

现在php test.php生成了您在问题:

rm -f test.log
php test.php
cat test.log

输出:

sh: line 2: warning: here-document at line 0 delimited by end-of-file (wanted `EOF')
  test
  EOF

显然,您的Bash部分缩进,这是一个无效的Bash语法。因此,您只需要删除Bash部分的缩进即可。至少,EOF不应该缩进。

我认为OP意味着纯粹的Bash的原始答案

exec执行一个命令,但您需要评估bash表达式。所以你需要eval

要使用eval构建命令,请使用以下命令:

eval "$(
cat <<'EOF'
cat >> test.log <<EOF2
log contents
EOF2
EOF
)"

因此,我们用"$()"构造了一个Bash变量。在变量中,我们创建了一个包含cat <<'EOF'EOF的here-doc字符串,其中单引号禁用参数替换,因此我们可以输入文本。(无评估)。然后,我们通过使用<<EOF2EOF2创建的另一个here-doc字符串编写了log contents

我们可以保存保存Bash变量,然后随意多次使用:

cmd="$(
cat <<'EOF'
cat >> test.log <<EOF2
log contents
EOF2
EOF
)"
rm test.log
eval "$cmd"; eval "$cmd"; eval "$cmd"
cat test.log

输出:

log contents
log contents
log contents

有关此处文档,请参阅文档。

相关内容

  • 没有找到相关文章

最新更新