【问题标题】:sh: 2: 1: not found - pass multiple php arguments to bash scriptsh: 2: 1: not found - 将多个 php 参数传递给 bash 脚本
【发布时间】:2016-05-09 17:02:02
【问题描述】:

我有一个简单的 bash 脚本,我从我的 php 代码中调用它来找出我的 apache 和 nginx 的版本。

$webroot = getcwd();

function get_version($name)
{
    global $webroot;

    switch ($name)
    {
        case "apache":
            $path   = shell_exec("whereis apachectl | awk '{ print $2 }'");
            $version = shell_exec("sudo $webroot/scripts/get_version $path 1 2>&1");
            break;
        case "nginx":
            $path = shell_exec("whereis nginx | awk '{ print $2 }'");
            $version = shell_exec("sudo $webroot/scripts/get_version $path 2 2>&1");
        default:
            echo "error";
    }

    return $version;
}

如您所见,我调用我的 bash 脚本并传递了两个参数。我在 bash 脚本中使用的路径和整数:

#!/bin/bash

_x=""
_programm=$1
_nr=$2

if [ "$_nr" -eq "1" ] ; then
    _x=$($_programm -v 2>/dev/null | grep -i 'version' | awk -F/ '{ print $4 }')
elif [ "$_nr" -eq "2" ] ; then
    _x=$($_programm -v 2>&1 | awk -F/ '{ print $2 }')
fi

cd $(pwd)
echo $_x

函数输出:

get_version("apache");     OUTPUT:     sh: 2: 1: not found
get_version("nginx");      OUTPUT:     sh: 2: 2: not found

但是,如果我在终端中执行 bash 脚本,那么它就可以工作并且我得到版本号作为输出,我用用户 root 和 www-data 都试过了,两者都有效。 bash脚本也进入visudo文件并具有执行权限,脚本用户为www-data。

./get_version /usr/sbin/apachectl 1     OUTPUT: 2.2.2
./get_version /usr/sbin/nginx 2         OUTPUT: 1.3

有人能解释一下为什么它在终端中有效,但在 php 中无效?

【问题讨论】:

  • 您不应该在print $2 中用双引号将$ 反斜杠吗?
  • 你的意思是这样的:print \$2?我试过了,但后来出现语法错误。

标签: php linux bash shell sh


【解决方案1】:

我找到了问题和解决方案。我的 php switch 语句中的命令whereis 出于某种未知原因向路径变量写入了一个空格字符,因此它没有工作。我在我的$path 变量上使用了rtrim 来修复它。

    case "apache":
        $path   = shell_exec("whereis apachectl | awk '{ print $2 }'");
        $path   = rtrim($path);
        ...

【讨论】:

  • 现在可以用了吗?另请注意,您收到的错误消息不是由bash 生成的,而是由sh 生成的。
【解决方案2】:

如果你在php的双引号内使用$,你必须转义它或切换到单引号:

...
$path   = shell_exec('whereis apachectl | awk \'{ print $2 }\'');
...
$path = shell_exec('whereis nginx | awk \'{ print $2 }\'');

【讨论】:

  • 嗯。我使用了您的代码,但不幸的是我仍然遇到同样的错误。我也认为这与我的代码没有什么不同。
  • 请为$path 和$version 字符串添加调试输出并发布您的问题。 echo $path . "\n" . $version; 在break 声明之前。
  • 我得到/usr/sbin/apachectl + sh: 2: 1: not found 和/usr/sbin/nginx + sh: 2: 2: not found
  • 如果我将$webroot 设置为/my/web/root 我得到sudo /my/web/root/scripts/get_version whereis apachectl | awk '{ print $2 }' 1 2>&1 这似乎没问题...
  • 请注意:您可以使用which apachectl 而不是whereis apachectl 来简化您的脚本。首先将只返回可执行文件的路径,没有其他信息。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-09-26
  • 2021-11-18
  • 2012-12-29
  • 1970-01-01
  • 1970-01-01
  • 2021-08-03
  • 1970-01-01
相关资源
最近更新 更多