Я пишу сценарий для автоматизации развертывания с компьютера под управлением Windows на сервер общего хостинга.
Я получаю разные результаты в зависимости от того, выполняю ли я команды через 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
но это не имеет значения.
Как я могу диагностировать / исправить эту проблему?
Последовательные вызовы exec ()
Если сделать это в интерактивной оболочке, то вывод, который вы получите для первого pwd, будет (в зависимости от того, как настроена ваша система) отличаться от вывода второго pwd. Однако приведенный фрагмент кода даст две одинаковые строки.
Причина этого заключается в том, что любые «изменения состояния», которые вы вносите в одноразовую оболочку, исчезают после запуска exec () и удаления канала.
Я вижу два варианта. Опция 1:
Попробуйте примеры интерактивных оболочек с read()
а также write()
функции, которые выглядят довольно уродливо для меня.
Вариант 2:
Напишите ваш сценарий как сценарий оболочки на сервере и вызовите сценарий одним $ssh->exec()
вызов.
Других решений пока нет …