我正在编写一个脚本来自动部署从我的Windows开发PC到共享托管服务器。
我得到的结果会有所不同,具体取决于我是通过Putty还是PHP 执行命令(两者都在我的电脑上运行)。
在putty中,当我通过SSH登录服务器时,我可以运行如下命令:
cd /www/
ls -la #outputs contents of /www
但是当我通过PHP使用phpseclib进行操作时,如下所示,任何cd
命令都被完全忽略:
<?php
require_once __DIR__.'/vendor/autoload.php';
use phpseclib\Net\SSH2;
$ssh = new SSH2('ssh.mydomain.com');
if (!$ssh->login('mydomain.com', 'mypassword')) {
trigger_error("Login Failed", E_ERROR);
}
echo $ssh->exec('pwd');
$ssh->exec('cd /www/');
echo $ssh->exec('pwd'); // unchanged
echo $ssh->exec('ls -la'); // does NOT output contents of /www/
echo $ssh->exec('ls /www/ -la'); // DOES output contents of /www/
在上面指定绝对URL是一种可接受的解决方法。但是,以下是一个主要问题。
如果我将文件stuff.zip
上传到/ www /然后尝试将其解压缩,则以下内容通过Putty工作:
unzip /www/stuff.zip -d /www/
但是如果我通过PHP尝试这个:
echo $ssh->exec('unzip /www/stuff.zip -d /www/');
我收到错误:
解压缩:无法找到或打开/www/stuff.zip,/www/stuff.zip.zip或/www/stuff.zip.ZIP。
我尝试了chmod 777 /www/stuff.zip
,但没有任何区别。
如何诊断/解决此问题?
答案 0 :(得分:2)
连续调用exec()
如果在交互式shell上完成,您为第一个pwd收到的输出(取决于系统的设置方式)将与第二个pwd的输出不同。但是,上面的代码片段将产生两条相同的行。
这样做的原因是,一旦运行exec()并删除了频道,您对一次性shell所做的任何“状态更改”都将消失。
我看到两个选项。选项1:
使用read()
和write()
函数试用interactive shell examples,这对我来说非常难看。
选项2:
将您的脚本编写为服务器上的shell脚本,并通过一次$ssh->exec()
调用来调用脚本。