使用Paramiko时Drush命令无法执行

2 投票
3 回答
2018 浏览
提问于 2025-04-17 10:33

我按照这里的步骤 http://jessenoller.com/2009/02/05/ssh-programming-with-paramiko-completely-different/ 用Python通过ssh连接到我的服务器。连接没问题,也能发送命令。

但是,当我运行stderr.readlines()时,每次都会显示下面的错误信息,即使命令看起来执行得很好。我已经关闭了连接并重启了Python,但结果还是一样。

这里有一个Python示例:

>>> stdin, stdout, stderr = myssh.exec_command("xyz")
>>> stderr.readlines()
['which: no php in (/usr/bin:/bin:/usr/sbin:/sbin:/big/dom/mydomain/pear/drush)\n', '/big/dom/mydomain/pear/drush/drush: line 89: exec: : not found\n', 'bash: xyz: command not found\n']

我已经安装了drush,使用起来也没问题。如果我在服务器上输入“which php”,我能看到它的位置,而不是上面的错误信息。我还故意发送了一些其他命令来看看能否清除错误信息,但结果是错误信息反而在后面叠加了。

在错误信息之后,我查看了提到的drush文件。这里是第89行:

exec "$php" $php_options "$SCRIPT_PATH" --php="$php" --php-options="$php_options" "$@"

我认为“which php”命令来自于这一行上面的$php变量

if [ ! -z "$DRUSH_PHP" ] ; then
  # Use the DRUSH_PHP environment variable if it is available.
  php="$DRUSH_PHP"
else
  # Default to using the php that we find on the PATH.
  # Note that we need the full path to php here for Dreamhost, which behaves oddly.  See http://drupal.org/node/662926
  php=`which php`

  # We check for a command line (cli) version of php, and if found use that.
  which php-cli >/dev/null 2>&1
  if [ "$?" = 0 ] ; then
    php=`which php-cli`
  fi

  # On MSYSGIT, we need to use "php", not the full path to php
  if [ ! -z "$MSYSTEM" ] && [ "x${MSYSTEM:0:5}" = "xMINGW" ] ; then
    php="php"
  fi
fi

文件的完整内容在这里:http://pastebin.com/29AXmHKF

如果我尝试执行任何drush命令,我都会遇到同样的错误。但如果我直接登录到服务器,而不使用python/paramiko,drush命令就能正常工作。

3 个回答

0

如果你通过ssh连接到那个服务器,然后运行 xyz,会发生什么呢?

你只有在真正查看错误信息的时候,才能看到错误提示,而不是在你发送命令的时候就能看到。(谢谢你,船长。)

错误信息看起来就像你的 xyz 是一个PHP脚本,并且它的开头有一行 #!which php 的标记。但是,系统找不到任何PHP可执行文件。这可能是因为在登录脚本中 PATH 没有设置正确。确保你了解在通过ssh连接到服务器时,哪个登录脚本会被执行(通常是 ~/.bash_profile 和/或 ~/.profile,而不一定是 ~/.bashrc)。

1

我用了Mike Ryan的解决方案(谢谢你,Mike!),但我发现信息是在标准输出(stdout)里,而不是标准错误(stderr)里。

stdin, stdout, stderr = server.ssh_client.exec_command("echo $PATH")
print stdout.readlines()
1

我首先需要搞清楚在执行命令时,$PATH 变量里到底有什么内容。我运行了

>>> stdin, stdout, stderr = myssh.exec_command("echo $PATH")
>>> stderr.readlines()

然后发现我的 $PATH 和在服务器上直接运行 echo $PATH 时显示的内容不一样!我只能猜测,在打开通道并发送我的命令后,某些额外的路径会被添加到 $PATH 变量中。

不过,$PATH 里确实包含了我之前在家目录的 .bashrc 文件中添加的 drush 的路径。所以,我只需要在那个文件里再添加 php 的路径就行了(尽管在服务器上运行 "echo $PATH" 时这个路径是存在的)。

现在我不再收到错误信息,可以顺利执行 drush 命令了。

撰写回答