ssh2_shell

(PECL ssh2 >= 0.9.0)

ssh2_shell请求交互式 shell

描述

ssh2_shell(
    资源 $session,
    字符串 $termtype = "vanilla",
    ?数组 $env = null,
    整数 $width = 80,
    整数 $height = 25,
    整数 $width_height_type = SSH2_TERM_UNIT_CHARS
): 资源|false

在远程端打开一个 shell 并为其分配一个流。

参数

session

SSH 连接链接标识符,从 ssh2_connect() 的调用中获得。

termtype

termtype 应该与目标系统 /etc/termcap 文件中的条目之一相对应。

env

env 可以作为名称/值对的关联数组传递,以便在目标环境中设置。

width

虚拟终端的宽度。

height

虚拟终端的高度。

width_height_type

width_height_type 应该是 SSH2_TERM_UNIT_CHARSSSH2_TERM_UNIT_PIXELS 之一。

返回值

如果成功,则返回一个流 资源,否则返回 false

示例

示例 #1 请求交互式 shell

<?php
$connection
= ssh2_connect('shell.example.com', 22);
ssh2_auth_password($connection, 'username', 'password');

$stream = ssh2_shell($connection, 'vt102', null, 80, 24, SSH2_TERM_UNIT_CHARS);
?>

参见

添加注释

用户贡献的注释 9 个注释

stefanov at uk dot ibm dot com
16 年前
不要使用 \n 来结束命令。一些服务器无法处理。始终使用 PHP 的标准行尾符:PHP_EOL

"suri at suribala dot com" 的示例应该修改如下(也把双引号改为单引号,以提高性能)

<?php

$con
=ssh2_connect('192.168.0.1', 22);
ssh2_auth_password($con, 'user', 'password');
$shell=ssh2_shell($con, 'xterm');
fwrite( $shell, 'cd /dir_one;'.PHP_EOL);
fwrite( $shell, 'ls -la;'.PHP_EOL);
fwrite( $shell, 'cd /dir_two;'.PHP_EOL);
fwrite( $shell, 'ls -la;'.PHP_EOL);

?>

欢呼,

Pimmy
tuxedobob at mac dot com
10 年前
请记住,当使用 ssh2_shell 时,远程系统的 EOL 可能与 PHP 的 EOL 不同,因此使用 PHP_EOL 可能不安全。Windows 的本机 EOL 是 \r\n,而 Unix 通常只是 \n,而经典的 Mac 由于某种原因是 \r。

如果您在 Windows (\r\n) 上运行 PHP 并 ssh 到 Unix 机器 (\n),您将最终发送额外的行。到目前为止,我的经验是它就像您什么也没输入一样,这可能会导致密码提示问题。

哦,还有 \n\r?不要这样做。没有人这样做。
galvao at galvao dot eti dot br
17 年前
回复 webmaster at spectreanime dot com

"由于某些奇怪的原因,在您的命令之后,您需要进行 sleep 以确保该命令已到达服务器并正在运行"

实际上,您需要做的是将字符串的阻塞设置为 true,这样它将在服务器发送数据到 STDOUT 之前等待,然后再进行回显。

所以,而不是

sleep(1);

只需执行

stream_set_blocking($stdio, true);

最好的问候,
webmaster at spectreanime dot com
19 年前
// 连接到 SSH 服务器
echo "连接 SSH ";
if (!($resource=@ssh2_connect("192.168.0.1"))) {
echo "[失败]<br />";
exit(1);
}
echo "[OK]<br />";

// 通过登录名/密码进行身份验证
echo "身份验证 ";
if (!@ssh2_auth_password($resource,"root","your_password")) {
echo "[失败]<br />";
exit(1);
}
echo "[OK]<br />";

// 我们需要一个 shell
echo "Shell stdio ";
if (!($stdio = @ssh2_shell($resource,"xterm"))) {
echo "[失败]<br />";
exit(1);
}
echo "[OK]<br />";

// 执行任何命令
// 注意在命令末尾添加 '\n'
$command = "/bin/ls /tmp\n";
fwrite($stdio,$command);

// 重要
// 由于某些奇怪的原因,在您的命令之后,您需要进行 sleep 以确保该命令已到达服务器并正在运行
sleep(1);

// 然后,您可以获取流以查看 stdio 上发生了什么
while($line = fgets($stdio)) {
flush();
echo $line."<br />";
}

// 关闭所有流始终更干净
fclose($stdio);

我真心希望我能帮助到某人 :)
josh at hydril dot com
17 年前
要运行 shell 脚本,其中包含交互式登录时具有的所有变量,请在命令前面添加 bash -l 或 sh --login。我使用的脚本创建一个 shell 脚本,使用 ssh2_scp_send 将该脚本复制到该框中,然后使用 ssh2_exec 执行该脚本。希望这能帮助到某人。

<?php

// 例子

$script1 = "bash -l /etc/rc.d/rc.httpd restart";

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

$stream = ssh2_exec($connection, $script1);
?>
vgopu1 at gmail dot com
17 年前
嗨,

我们也可以使用 shell_exec 来执行多个相关的命令
用分号 (;) 分隔。

我发现了一个问题,有时会导致执行复杂的 Java、C/C++ 程序出现问题。我们只需要设置必要的环境变量即可解决。我在 .bash_profile 中设置了一个环境变量。这个变量通常在通过 shell 登录到我的帐户时会自动设置。但当使用 ssh2_connect() 时,.bash_profile 中的环境变量不会被设置,我们需要使用 shell_exec() 导出所需的变量。

示例

$conn = ssh2_connect($ipaddress);
ssh2_auth_password($conn,$username,$passwd);
$cmd1="/path/to/program1";
$cmd2="/path/to/program2";
$env1="export Variable_name1=path1";
$env2="export Variable_name2=path2"
$stream = ssh2_exec($connection,"$env1; $env2; $cmd1; $cmd2");//这将执行所有命令并返回
// 流
stream_set_blocking($stream, true);
while($o=fgets($stream)){
echo $o.'<br>';
}

...
...

谢谢,
Vikram Gopu .
http:\\my.lsu.edu/vgopu1
nogueiraconsultoria at gmail dot com
4 年前
我了解了用于执行多个命令的工作脚本。该脚本以“命令”为索引,返回每个命令的输出数组。

注意:ssh2_cmd() 不适用于多个命令,因此使用 ssh2_shell()。请注意不同操作系统上的 EOL 类型。我在每个命令的末尾使用了“\n”,但可能还有其他选项,如“<br>”、“; ”等;

$connection = ssh2_connect($input_host_ip, 22);

if (false === $connection) {
error_log("ERROR 函数 SSH_UMTELECOM: 连接失败!\n",3,$log_file);
exit();
}else{
if($debugar){error_log("SSH_UMTELECOM: 连接到 $input_host_ip 成功!\n",3,$log_file);}

$auth = @ssh2_auth_password($connection, $user, $pass);
if (false === $auth) {
error_log("ERROR 函数 SSH_UMTELECOM: 在 $input_host_ip 上认证失败(用户:$user)!\n",3,$log_file);
exit();
}else{
if($debugar){error_log("SSH_UMTELECOM: 连接到 $input_host_ip 成功!\n",3,$log_file);}

error_log("启动流:$connection\n",3,$log_file);
$output_array = array();
$shell = ssh2_shell($connection, 'vt100');

foreach($input_cmd as $cmd){
if($debugar){error_log("shell: $cmd\n",3,$log_file);}
$output_stream = ""; # 清空变量以进行每次迭代
fwrite($shell, "$cmd\n"); # 不要忘记在每个命令末尾加上“\n”
#stream_set_blocking($shell, true); # 不起作用,无限期等待
sleep(2); # 2 秒,用于高延迟网络
while($output_streams = fgets($shell)){
$output_stream .= $output_streams;
flush();# 清空内容以进行下次迭代
}
$output_array[] = $output_stream; # 收集每个命令的返回值
}
fclose($shell); # 从 shell 注销
}# 结束 if false === $auth
}# 结束 if false === $conenection
tsschulz at gmx dot net
13 年前
在我的情况下,ssh2_shell 并不总是起作用。遇到了很多问题
- 如果使用 stream_get_contents,命令永远不会执行
- 使用 while ($buf = fgets...) 循环永远不会停止
- 在 stream_set_blocking 之前没有使用 sleep(1),命令并不总是执行。有人知道原因吗?
这就是我所做的事情,而且它可以正常工作,但我认为它不是应该有的样子
<?php
$strCommand
= 'tar -C /path/to/extract -xjf /path/from/file.tar.bz2';
$sshStream = ssh2_shell($this->sshSession, 'xterm', null, 120, 24, SSH2_TERM_UNIT_CHARS);
fwrite($sshStream, $strCommand . PHP_EOL);
sleep(1);
stream_set_blocking($sshStream, true);
$sshUntarRetval = "";
while (
$buf = fgets($sshStream,4096)) {
flush();
$sshUntarRetval .= $buf;
if (
strpos($buf, 'tar -C') !== false)
{
break;
}
}
fclose($sshStream);
?>
suri at suribala dot com
19 年前
使用 ssh_exec,一次只能执行一条命令。但是,ssh_shell 提供了更大的灵活性。

以下是一个示例

<?php

$con
=ssh2_connect('192.168.0.1', 22);
ssh2_auth_password($con, "user", "password");
$shell=ssh2_shell($con, 'xterm');
fwrite( $shell, "cd /dir_one\n");
fwrite( $shell, "ls -la\n");
fwrite( $shell, "cd /dir_two\n");
fwrite( $shell, "ls -la\n");

?>

感谢 Sara 的实现和帮助!
To Top