virtctl 在通过命令行执行时有效,但在 php exec() 中无效

virtctl works when executed via command line but not from php exec()

我正在尝试 运行 kubectl virt 命令通过 PHP 管理我的虚拟机。首先,我使用以下代码使用 phpseclib 登录到我的服务器:

$ssh = new SSH2('localhost');
if (!$ssh->login('root', 'rootPassword')) {
    throw new \Exception('Login failed');
}

这部分工作正常,当我尝试 运行 $ssh->exec('whoami && echo $PATH') 时,我得到以下输出:

root
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

但是,每当我尝试通过 PHP 运行 kubectl virt 时,我都会得到以下输出:

error: unknown command "virt" for "kubectl"

kubectlkubectl virt 在我通过终端 运行 时工作得很好,但不知何故不能与 PHP exec() 一起工作。我还尝试通过终端检查 $PATH,但得到了不同的输出:

/root/.krew/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

我认为这可能是因为 $PATH 但有趣的部分是当我尝试通过终端 运行 sudo kubectl virt 我也得到同样的错误:

error: unknown command "virt" for "kubectl"

那时,我完全迷路了,甚至不知道去哪里找问题。感谢所有的回答。

当您发出 ad-hoc ssh 命令时,您没有使用交互式 shell,并且根据您的默认 shell 行为,它可能加载也可能不加载您的 .bashrc 文件。有关详细信息,请参阅 https://serverfault.com/questions/936746/bashrc-is-not-sourced-on-ssh-command and Running command via ssh also runs .bashrc?

所以默认情况下,krew 会修改您的 PATH 变量,并将其 bin 路径附加到它,即我的配置包含 export PATH="${KREW_ROOT:-$HOME/.krew}/bin:$PATH"。但 kubectl 插件到底是什么?通常它只是一个二进制文件,名称为 kubectl-plugin_name 。所以通过调用 which kubectl-virt 你可以很容易地知道你的 virt 二进制文件在哪里并直接调用它,所以像

$ssh->exec('~/.krew/bin/kubectl-virt')

应该可以

另一种方法是自己修改 PATH,设置 PATH=$PATH:~/.krew/bin 应该可以,至少在我的情况下是这样

ssh localhost 'PATH=$PATH:~/.krew/bin kubectl virt'

工作得很好。

您可以尝试在您的 shell 配置中强制加载 .bashrc,但我个人认为这是一种不好的做法,并且 ssh 命令通常不会加载 rc 文件是有原因的,命令执行速度和一致性系统之间是首先想到的。

关于 sudo,实际上并不奇怪,因为没有 -E-i 标志它不会加载您当前的环境/不会启动交互 shell。有关详细信息,请参阅 https://unix.stackexchange.com/questions/228314/sudo-command-doesnt-source-root-bashrc