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字符串,其中单引号禁用参数替换,因此我们可以输入文字内容(无需评估)。然后,通过使用由
<<EOF2
和
EOF2
创建的另一个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”的信息。
<<<BASH
是一个 here-string 而不是 here-doc。Here-string 不需要定界符来标记其结尾。 - sjsam