如何从PHP调用bash函数?

时间:2015-11-01 23:27:56

标签: php bash

这是我的工作流程:

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 - 但没有运气。

4 个答案:

答案 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"');