PHP中的heredoc内使用Shell heredoc

4

我在一个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。但是我很好奇为什么在这种特定情况下这种方法不起作用。

编辑。 我澄清了代码,以便更清楚地说明我正在谈论运行shell命令的php。


<<<BASH 是一个 here-string 而不是 here-doc。Here-string 不需要定界符来标记其结尾。 - sjsam
1个回答

2

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字符串,写入日志内容。我们可以保存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

请参阅这里文档了解更多关于“Here Documents”的信息。

tldp 的 Bash 指南已经过时,有些情况下甚至是错误的。我建议使用 Bash Guide 代替。 - Rany Albeg Wein
我有没有错过什么,或者这个回答根本没有涉及到 PHP? - santiago arizti
@santiagoarizti,啊,是的。不知怎么的,我想到了纯Bash。我会修正我的答案。 - Ruslan Osmanov
可能你是对的,我可能有一些缩进问题。我会将其标记为正确,谢谢。 - santiago arizti

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接