这是我的工作流程:
ubuntu$ cat test.sh
#!/bin/bash
function getNumber
{
echo 1
}
ubuntu$ cat test.php
<?php
echo shell_exec("getNumber");
ubuntu$ source test.sh
ubuntu$ getNumber
1
ubuntu$ php test.php
sh: 1: getNumber: not found
是否有可能以某种方式更改php脚本(或可能是其调用),因此它将打印&#34; 1&#34;?我正在寻找一种方法来从php 中调用 bash函数。
我从这里尝试了一些解决方案:Is it possible to source a *.sh file using PHP CLI and access exported Env vars in the PHP script?
其中一个是:./test.sh && php -f test.php
- 但没有运气。
答案 0 :(得分:2)
这是一个能够做你想要的功能。它加载产生一个bash进程,该进程获取bash脚本,然后运行该函数。
它使用proc-open(http://php.net/manual/en/function.proc-open.php)
<?php
$value = runBashFunction("test.sh", "getNumber");
var_dump($value);
function runBashFunction($bashfile, $bashfunction) {
$descriptorspec = array(
0 => array("pipe", "r"), // stdin is a pipe that the child will read from
1 => array("pipe", "w"), // stdout is a pipe that the child will write to
2 => array("pipe", "w") // stderr is a pipe too
);
$cwd = '.';
$env = array();
$process = proc_open('bash', $descriptorspec, $pipes, $cwd, $env);
if (is_resource($process)) {
fwrite($pipes[0], "source $bashfile\n");
fwrite($pipes[0], "$bashfunction\n");
fclose($pipes[0]);
$output = stream_get_contents($pipes[1]);
$error = stream_get_contents($pipes[2]);
fclose($pipes[1]);
fclose($pipes[2]);
// It is important that you close any pipes before calling
// proc_close in order to avoid a deadlock
//
$return_value = proc_close($process);
//note, $error and $return_value are discarded
return $output;
}
return null;
}
?>
答案 1 :(得分:1)
在这个特定示例中,您可以将source
命令和函数本身组合到同一个PHP exec调用中:
var_dump(
shell_exec('source test.sh && getNumber')
); // string(2) "1
"
如果您需要删除回车符,请修剪结果。
答案 2 :(得分:1)
另一种方法是将要执行的函数的名称传递给bash脚本。
test.sh 是包含您要执行的函数的bash脚本:
#!/bin/bash
function getNumber
{
echo "fnGetNumber"
}
# Test if the first parameter names a function
if [ "$(type -t $1)" = function ]; then
$1
else
echo "$1 is an invalid function"
fi;
test.php 是将调用该函数的PHP脚本:
#!/usr/bin/php
<?php
echo `./test.sh getNumber`;
请注意,这需要您传递脚本的名称以及函数名称。
将功能测试归功于:https://stackoverflow.com/a/85903/2182349
如果您想将参数传递给函数,可以使用:
更新了 test.sh :
#!/bin/bash
function getNumber
{
echo "fnGetNumber $1"
}
if [ "$(type -t $1)" = function ]; then
$1 "$2"
else
echo "$1 is an invalid function"
fi;
更新了 test.php
<?php
$parm = 'toast';
echo `./test.sh getNumber $parm`;
答案 3 :(得分:0)
我找到了另一种解决方案。问题出在 Ubuntu 及其dash
正在运行sudo dpkg-reconfigure dash
并回复no
已将dash
更改为bash
,这是{php}提供source
命令的原因。
WAS :ls -la /bin/sh
=&gt; /bin/sh -> dash
现在:ls -la /bin/sh
=&gt; /bin/sh -> bash
启用source
后,此功能正常:
echo shell_exec('source /full/path/to/file/test.sh && getNumber abc def');
是什么帮助了我: https://stackoverflow.com/a/13702876/4621324
更改期间一个注意事项:Ubuntu警告我:使用dash作为系统shell将提高系统的整体性能。它不会改变呈现给交互式
的shell由于我不想在全球范围内将dash
更改为bash
,因此我决定采用此解决方案:
echo shell_exec('/bin/bash -c "source /full/path/to/file/test.sh && getNumber abc def"');