Ssh запустить php скрипт

ssh2_exec

Запуск команды на удалённом сервере и выделение для неё канала.

Список параметров

Идентификатор соединения SSH, полученный из ssh2_connect() .

env может передаваться как ассоциативный массив пар имя/значение, представляющие переменные окружения, которые нужно установить перед запуском команды.

Ширина виртуального терминала.

Высота виртуального терминала.

width_height_type должен быть SSH2_TERM_UNIT_CHARS или SSH2_TERM_UNIT_PIXELS .

Возвращаемые значения

Возвращает поток в случае успешного выполнения или false в случае возникновения ошибки.

Примеры

Пример #1 Выполнение команды

$connection = ssh2_connect ( ‘shell.example.com’ , 22 );
ssh2_auth_password ( $connection , ‘username’ , ‘password’ );

$stream = ssh2_exec ( $connection , ‘/usr/local/bin/php -i’ );
?>

Смотрите также

  • ssh2_connect() — Подключение к SSH-серверу
  • ssh2_shell() — Запрашивает интерактивный терминал
  • ssh2_tunnel() — Открыть туннель через удалённый сервер

User Contributed Notes 17 notes

The «pty» parameter is not documented.

You should pass a pty emulation name («vt102», «ansi», etc. ) if you want to emulate a pty, or NULL if you don’t.

Passing false will convert false to a string, and will allocate a «» terminal.

There doesn’t appear to be a way to get data from BOTH stderr and stdout streams simultaneously, or at least I’ve yet to find one.

The following code *should* get the error message written to stderr, but if the call to stream_get_contents() for stdout is run first, the subsequent call for stderr won’t return anything.

If the order of the statements is reversed, the call for stderr will return any errors and call for stdout will return nothing

// Run a command that will probably write to stderr (unless you have a folder named /hom)
$stream = ssh2_exec ( $connection , «cd /hom» );
$errorStream = ssh2_fetch_stream ( $stream , SSH2_STREAM_STDERR );

// Enable blocking for both streams
stream_set_blocking ( $errorStream , true );
stream_set_blocking ( $stream , true );

// Whichever of the two below commands is listed first will receive its appropriate output. The second command receives nothing
echo «Output: » . stream_get_contents ( $stream );
echo «Error: » . stream_get_contents ( $errorStream );

// Close the streams
fclose ( $errorStream );
fclose ( $stream );

?>

My initial suspicion is that either a) I’ve done something wrong or b) the blocking nature of both streams means that by the time first stream has received data and returned, the buffer for the second stream has already emptied.

I’ve done preliminary tests with blocking disabled, but haven’t had any luck there either.

The following function can be used to read both stdout and stderr even if both streams contain gigabytes of data. It solves most problems mentioned in other comments, like blocking, like further using the existing connection etc.

function ssh2_run($ssh2,$cmd,&$out=null,&$err=null) $result=false;
$out=»;
$err=»;
$sshout=ssh2_exec($ssh2,$cmd);
if($sshout) $ssherr=ssh2_fetch_stream($sshout,SSH2_STREAM_STDERR);
if($ssherr) # we cannot use stream_select() with SSH2 streams
# so use non-blocking stream_get_contents() and usleep()
if(stream_set_blocking($sshout,false) and
stream_set_blocking($ssherr,false)
) $result=true;
# loop until end of output on both stdout and stderr
$wait=0;
while(!feof($sshout) or !feof($ssherr)) # sleep only after not reading any data
if($wait)usleep($wait);
$wait=50000; # 1/20 second
if(!feof($sshout)) $one=stream_get_contents($sshout);
if($one===false)< $result=false; break; >
if($one!=»)< $out.=$one; $wait=0; >
>
if(!feof($ssherr)) $one=stream_get_contents($ssherr);
if($one===false)< $result=false; break; >
if($one!=»)< $err.=$one; $wait=0; >
>
>
>
# we need to wait for end of command
stream_set_blocking($sshout,true);
stream_set_blocking($ssherr,true);
# these will not get any output
stream_get_contents($sshout);
stream_get_contents($ssherr);
fclose($ssherr);
>
fclose($sshout);
>
return $result;
>

I believe most of the problem that people are having here is that there is a misconception about what blocking *really* means.

Blocking means a read from the *stream* will wait until there is data. Not necessarily all the data from the application — but *some*. So it won’t help you at all if you’re executing a command that doesn’t write to stdout, or writes a whole lot of data.

1. If you need to know that a silent program is done via ssh2_exec, you’ll need to signal it to yourself. ssh2_exec will *not* block execution until the command is done executing. And 2 consecutive ssh2_execs may execute asynchronously. You could also log into a shell via ssh2_shell and parse up to the next prompt — but that’s overkill. You can also do this by adding on some sort of sentinel at the end of your command, such as echo «@,» and then block on reads until you see a «@.» Ensure «@» won’t appear in the output, or escape the output via some encoding mechanism if you can’t do that.

2. If the program takes awhile, you have the same problem. You need to read until you’re done. So you need a sentinel value like the above.

3. Sleep() is just a bad idea here. Commands rarely take the same amount of time to execute a command twice. It may be OK if you’re doing *one* thing and can just wait 5 seconds. But that’s not cool if it’s something you’re doing in a loop.

Executing remote Windows commands.
After some hair pulling, I thought I’d suggest a couple things that might help others:

1. Use ‘ssh2_fetch_stream’ to open a stderr stream according to the manual.
2. Windows shell commands require ‘cmd /C [command]’ to execute. (I had forgotten this)

// code fragment
$stdout_stream = ssh2_exec ( $connection , ‘cmd /C dir’ );
$stderr_stream = ssh2_fetch_stream ( $stdout_stream , SSH2_STREAM_STDERR );
?>

I didn’t realize the need for the ‘cmd /C’ until I saw the stderr response ‘dir: not found’.

Here’s what I use for doing ssh2_exec for long running scripts, expanding on other examples. It waits for a timeout and checks if both streams are finished. Does not use blocking and it gets data from both STDOUT and STDERR.

$stdout = ssh2_exec ( $ssh , $cmd );
$stderr = ssh2_fetch_stream ( $stdout , SSH2_STREAM_STDERR );
if (!empty( $stdout ))

$t0 = time ();
$err_buf = null ;
$out_buf = null ;

$err_buf .= fread ( $stderr , 4096 );
$out_buf .= fread ( $stdout , 4096 );

$done = 0 ;
if ( feof ( $stderr )) $done ++;
>
if ( feof ( $stdout )) $done ++;
>

// Wait here so we don’t hammer in this loop
sleep ( 1 );

echo «STDERR:\n $err_buf \n» ;
echo «STDOUT:\n $out_buf \n» ;

> else echo «Failed to Shell\n» ;
>
?>

Adjust your timeout as necessary.

Источник

Как запустить PHP-скрипт через командную строку?

Для чего нужен запуск php-скриптов через командную строку? Он позволяет проверить и отладить работу скриптов на новой версии PHP или с иными значениями PHP-директив, не меняя их для всего сайта целиком (например, если на более высокой версии PHP скрипт работает некорректно, то его запуск через консоль не нарушит работу сайта, что может произойти если сменить версию на самом сайте).

Также это позволит обойти ограничение времени работы скриптов при запуске их через браузер, которое есть на всех хостингах (делается это для того, чтобы некорректно написанные скрипты, например зацикленные, не могли нарушить работу сервера в целом) — скрипт будет работать, пока достаточно ресурсов на услуге хостинга.

Подключить SSH-доступ

1. Чтобы иметь возможность запустить PHP скрипт из командной строки, необходимо иметь услугу хостинга с активным SSH-доступом. Проверить, активен ли SSH-доступ у Вас, можно в панели хостинга в разделе «Инструменты». Если при открытии данного раздела есть пункт «Shell-клиент», то SSH-доступ на Вашей услуге хостинга открыт.

Shell-клиент в панели управления ISPmanager

Если же такого пункта нет, то Вам нужно через личный аккаунт создать запрос в службу поддержки, чтобы данный доступ предоставили. Как создать запрос в техподдержку, читайте на нашем сайте.

Подключение по SSH

2. После получения SSH-доступа, подключимся к нашей услуге через любой SSH-клиент.

Либо можно использовать Shell-клиент из панели хостинга, но он не совсем удобен, для тех случаев, когда команды требуется откуда-то копировать и затем вставлять в консоль.

Команды для подключения через терминал Linux или утилиту PowerShell Windows будет иметь следующий вид:

ssh -p 34716 логин@имя или IP-адрес сервера.

Логином служит имя пользователя от панели хостинга.

Примеры:
ssh -p 34716 usertest@fry.handyhost.ru

Подключение по SSH

ssh -p 34716 usertest@109.95.210.219

После подключения можем приступать к запуску.

Запуск PHP-скрипта

3. Самый простой вариант — команда вида php/путь/к/скрипту. Такая команда запустит указанный Вами скрипт через нативную версию PHP (системную версию PHP, которая по умолчанию устанавливалась для ОС сервера с Вашей услугой хостинга), с теми настройками, которые установлены на сервере по умолчанию.

Пример:
php /var/www/usertest/data/www/fryhh.onhh.ru/info.php Как запустить PHP-скрипт на хостинге через терминал
Узнать какая версия PHP используется по умолчанию на сервер с Вашей услугой можно командой: php -v
Как узнать какая версия PHP на хостинге в терминале

В данном примере версией PHP, используемой по умолчанию является версия 7.3.

4. Для запуска через конкретную версию PHP указать в нашей команде путь к сборке PHP соответствующей версии. Команда будет иметь вид:
/opt/alt/phpXX/usr/bin/php/путь/к/скрипту
Примеры:
/opt/alt/php53/usr/bin/php /var/www/usertest/data/www/fryhh.onhh.ru/info.php
/opt/alt/php72/usr/bin/php /var/www/usertest/data/www/fryhh.onhh.ru/info.php
/opt/alt/php81/usr/bin/php /var/www/usertest/data/www/fryhh.onhh.ru/info.php
Список доступных сборок:
/opt/alt/php51/usr/bin/php
/opt/alt/php52/usr/bin/php
/opt/alt/php53/usr/bin/php
/opt/alt/php54/usr/bin/php
/opt/alt/php55/usr/bin/php
/opt/alt/php56/usr/bin/php
/opt/alt/php70/usr/bin/php
/opt/alt/php71/usr/bin/php
/opt/alt/php72/usr/bin/php
/opt/alt/php73/usr/bin/php
/opt/alt/php74/usr/bin/php
/opt/alt/php80/usr/bin/php
/opt/alt/php81/usr/bin/php
На скриншоте запуск скрипта через версию PHP 5.1.

запуск скрипта через версию PHP 5.1 в терминале

5. Важно — если в настройки той версии PHP, через которую запускается скрипт, были внесены изменения через панель хостинга, то скрипт также запустится с этими настройками PHP. Как поменять настройки php.ini, читайте в нашей статье.

Скрипт, используемый в качестве примера в данной статье, выводит информацию о версии и настройках PHP, через которые он запущен.

На скриншоте показаны результаты его запуска через нативную версию PHP 7.4, для которой значение параметра memory_limit менялось и версию PHP 7.2, для которой изменения настроек не производилось (к результатам работы применен фильтр через функцию grep по параметру memory_limit).

результаты запуска скрипта через нативную версию PHP 7.4 в терминале

Если нам по каким-то причинам требуется запустить скрипт через определенную версию PHP с настройками, отличающимися от тех, что заданы для этой версии через панель, то можно использовать опцию -n — не будут учитываться никакие ini-файлы и соответственно внесенные через панель изменения, либо опцию -d для переопределения конкретной директивы.

Примеры:
/opt/alt/php74/usr/bin/php -d memory_limit=1000M /var/www/usertest/data/www/fryhh.onhh.ru/info.php

результаты запуска скрипта через PHP 7.4 с memory_limit на 350 Мб

/opt/alt/php74/usr/bin/php -n /var/www/usertest/data/www/fryhh.onhh.ru/info.php

На скриншоте показаны результаты запуска скрипта через PHP 7.4, для которой значений параметра memory_limit установлено на 350 Мб через панель хостинга. Запуск производился с опцией -n, опцией -d memory_limit=1000M, которая устанавливает значение параметра memory_limit на 1000 Мб и без дополнительных опций. К результатам вывода также применен фильтр через функцию grep по параметру memory_limit.

Источник

Читайте также:  Background color yellow in html
Оцените статью