我正在编写一个脚本,用于从我的windows开发PC自动部署到共享主机服务器。
我得到不同的结果取决于我是否通过Putty或PHP执行命令(都在我的PC上运行)。
在putty中,当我通过SSH登录到服务器时,我可以运行如下命令:
cd /www/
ls -la #outputs contents of /www
但是当我使用phpseclib通过PHP执行时,如下所示,任何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/');
我得到错误:
unzip:无法找到或打开/www/stuff.zip,/www/stuff.zip或/www/stuff.zip.zip。
我试过chmod 777 /www/stuff.zip
,但无济于事。
我如何诊断/解决这个问题?
来自文档:
连续调用exec()
如果在交互式shell上执行,您将收到的第一个pwd的输出(取决于您的系统设置方式)将与第二个pwd的输出不同。然而,上面的代码片段将产生两行相同的代码。
这样做的原因是任何"状态变化"。一旦exec()被运行并且通道被删除,那么一次性shell就会消失。
我看到两个选项。选项1:
尝试使用read()
和write()
函数的交互式shell示例,对我来说看起来很丑。
选项2:
在服务器上将脚本编写为shell脚本,并使用单个$ssh->exec()
调用该脚本。