用 php 远程登录。控制远程 APC PDU
Posted
技术标签:
【中文标题】用 php 远程登录。控制远程 APC PDU【英文标题】:Telnet with php. Control remote APC PDU 【发布时间】:2012-08-23 17:34:41 【问题描述】:我正在尝试通过执行一些 php 命令来控制远程电源开关。
我正在使用一个 telnet 库来建立 telnet 连接:http://www.soucy.org/project/cisco/source.php
我的连接函数如下所示:
public function connect()
$this->_connection = fsockopen($this->_hostname, $this->_port, $errno, $errstr, $this->_timeout);
if ($this->_connection === false)
die("Error: Connection Failed for $this->_hostname\n");
// if
stream_set_timeout($this->_connection, $this->_timeout);
$this->_readTo(':');
if (substr($this->_data, -9) == 'Username:')
$this->_send($this->_username);
$this->_readTo(':');
// if
$this->_send($this->_password);
$this->_send(''); //blank space, because we need to press <Enter> for the second login prompt
//Login Second time
$this->_send($this->_username2);
$this->_send($this->_password2);
发送函数如下所示:
private function _send($command)
fputs($this->_connection, $command . "\r\n");
因此,如果我们要控制远程电源开关,则有一个菜单。在这个菜单中,用户可以这样导航:
------- 控制台 -------------------------------------- ------------------
1- Device Manager
2- Network
3- System
4- Logout
<ESC>- Main Menu, <ENTER>- Refresh
当我们按 1 时,我们将转到另一个菜单:
------- 设备管理器 -------------------------- ------------------
1- Bank Monitor
2- Outlet Management
3- Power Supply Status
<ESC>- Back, <ENTER>- Refresh
等等...所以我们只需输入这些数字就可以访问我们想要的插座。
重新加载插座的功能(插座号 22):
public function ReloadOutlet22()
$this->_send('1'); // Access Device Manager
$this->_send('2'); // Access Outlet Management
$this->_send('1'); // Outlet Control/Configuration
$this->_send(); // '<Enter> to continue'
$this->_send('22'); // Access Outlet number 22
$this->_send('6'); // Delayed Reboot (reboot with 5 sec delay)
$this->_send('YES'); // 'Yes' to continue
$this->_send(); // <Enter> to continue'
//Everything is working till there. I can successfully reload the outlet which I want. After the reload I want to go to the main menu and logout from this console.
$this->_send('\e'); // <Esc> - back
$this->_send('\e'); // <Esc> - back
$this->_send('\e'); // <Esc> - back
$this->_send('\e'); // <Esc> - back
$this->_send('\e'); // <Esc> - back
$this->_send('4'); // Logout
所以有问题。下次,当我想重新加载另一个插座时,例如编号为 23 的插座,我无法成功登录 APC PDU。我可以在登录提示中看到尝试使用 '\e' 作为用户名和密码。
所以也许你们有一个想法,为什么在成功重新加载后我的代码不能正常工作?为什么我无法返回主菜单并退出?
感谢您的宝贵时间。
【问题讨论】:
您确定需要 5 个 esc 序列才能返回吗?当您简单地断开并重新连接时会发生什么? 如果我只是简单地断开并重新连接,我仍然会登录。如果我想重新加载不同的电源插座,如果我可以注销会更简单。否则我的“重启插座”序列将不起作用。感谢您的回答! 您的问题描述听起来好像您发送的 esc 序列比必要的多,也许您需要在回来的路上解析屏幕? 如果我想进入可以通过按数字 4 使用“注销”命令的主菜单,我需要使用 5 个转义序列。但看起来脚本有时会在发送“YES”命令后停止。 【参考方案1】:您可能需要在 "\e" 周围加上双引号 - 单引号将其视为文字字符串(没有像 \n 这样的转义序列)
$this->_send("\e"); // <Esc> - back
如果这不起作用,请使用
$this->_send(chr(27)); // <Esc> - back
使用数字 ASCII 值发送转义键
http://php.net/manual/en/function.chr.php
【讨论】:
我不知道为什么,但是会话以某种方式挂起,当我尝试重新加载另一个插座时无法正常登录。感谢您提供转义键序列,我会使用它! 当通过 SSH 连接到服务器时,您可能需要在发送密码后休眠一两秒才能运行登录脚本(以及启动硬盘驱动器),然后再发送任何命令。在您发送密码和实际看到登录提示之间,服务器将丢弃任何输入。睡 2-3 秒为我解决了这个问题。 是的,亲爱的罗伯特,我尝试使用它,但如果我使用例如 sleep(3);在我的 php 代码上执行命令我会收到以下错误:严重性:通知消息:fputs(): send of 2 bytes failed with errno=32 Broken pipe 也许您需要在第二次登录之前读取服务器发送的所有内容(以清除缓冲区) 另外,您的发送命令会附加 \r\n,因此您实际上是在按APC 提供控制台(基于文本的菜单驱动),以及它们的命令行界面(“CLI”),它接受各种特定于控制 PDU 插座的命令行。
要使用命令行界面而不是控制台,请在使用 telnet 登录时将“-c”附加到您的密码 - 即,如果您的 telnet 密码是“abcdefg”,则使用密码“abcdefg -c”登录进入 CLI。 CLI 命令提示符是“APC>”。
重启(重启)插座的 CLI 命令很简单:
APC> reboot x
(x = the outlet number to power cycle)
【讨论】:
谢谢!太棒了,一直在找这个!我会努力的!以上是关于用 php 远程登录。控制远程 APC PDU的主要内容,如果未能解决你的问题,请参考以下文章