【问题标题】:Shell heredoc inside php heredocphp heredoc 中的 shell heredoc
【发布时间】:2016-08-24 22:24:52
【问题描述】:

我在 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 命令。

【问题讨论】:

  • &lt;&lt;&lt;BASH 是这里的字符串,而不是 here-docHere-string 不需要分隔符来标记其结尾。

标签: php bash shell heredoc


【解决方案1】:

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 &lt;&lt;'EOF'EOF 的 here-doc 字符串,其中单引号禁用参数替换,因此我们可以输入文字文本。(无评估)。然后我们通过使用&lt;&lt;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

请参阅here documents 的文档。

【讨论】:

  • tldp Bash 指南已经过时,在某些情况下完全是错误的。我推荐Bash Guide
  • 我是否遗漏了什么或者这个答案中根本没有 php 发生?
  • @santiagoarizti,啊,是的。不知何故,我想到了纯 Bash。我会修正我的答案。
  • 奇怪,也许你是对的,我一定有一些缩进。我会将其标记为正确,谢谢
猜你喜欢
  • 2015-12-29
  • 2013-02-24
  • 1970-01-01
  • 1970-01-01
  • 2013-02-17
  • 2016-12-11
  • 2012-02-07
  • 2011-08-17
  • 2011-05-21
相关资源
最近更新 更多