【问题标题】:PHPSECLIB ->exec and ->write not finishing before returning truePHPSECLIB ->exec 和 ->write 在返回 true 之前未完成
【发布时间】:2015-10-26 23:57:47
【问题描述】:

我正在尝试将一个非常耗时的脚本从 php 端点调用到运行 matlab 的服务器。

我决定使用 phpseclib,因为很多人推荐它的可移植性。我开始怀疑我是否做出了正确的决定。也许你可以帮忙!

我遇到的问题是,无论我如何运行以下命令,它总是在完成之前返回 true。

 $read = $sftp->read('/.*@.*[$|#]/', NET_SSH2_READ_REGEX);
 $sftp->write("matlab -nodisplay -nodesktop -nosplash -logfile remote_matlab.out -r \"cd('/some_supporting_files'); some_function('/some_data_I_just_uploaded.txt'); exit;\"\r\n");
 $read2 = $sftp->read('/.*@.*[$|#]/', NET_SSH2_READ_REGEX);

我也试过这样运行:

$sftp->exec("matlab -nodisplay -nodesktop -nosplash -logfile remote_matlab.out -r \"cd('/some_supporting_files'); some_function('/some_data_I_just_uploaded.txt'); exit;\"");

我已经测试了有关它的所有内容(例如,文件在那里,它不会出错等)它可以正确启动,但只是没有完成。我需要知道它何时完成,因为我需要下载它创建的文件。

如果我添加一个$sftp->setTimeout(40),它每次都有效,但如果他们不需要,我不希望有人等那么久,我也不能保证到那时脚本会回来。

一旦我得到这个工作,我仍然需要从 Angular ping 这个脚本。

这是我得到的日志:

"log": [
    "<-",
    "->",
    "<- NET_SSH2_MSG_KEXINIT (since last: 0.158, network: 0.038s)",
    "-> NET_SSH2_MSG_KEXINIT (since last: 0.001, network: 0s)",
    "-> NET_SSH2_MSG_KEXDH_INIT (since last: 0.453, network: 0s)",
    "<- NET_SSH2_MSG_KEXDH_REPLY (since last: 0.038, network: 0.038s)",
    "-> NET_SSH2_MSG_NEWKEYS (since last: 0.457, network: 0s)",
    "<- NET_SSH2_MSG_NEWKEYS (since last: 0, network: 0s)",
    "-> NET_SSH2_MSG_SERVICE_REQUEST (since last: 0.006, network: 0s)",
    "<- NET_SSH2_MSG_SERVICE_ACCEPT (since last: 0.105, network: 0.105s)",
    "-> NET_SSH2_MSG_USERAUTH_REQUEST (since last: 0, network: 0s)",
    "<- NET_SSH2_MSG_USERAUTH_SUCCESS (since last: 0.071, network: 0.071s)",
    "-> NET_SSH2_MSG_CHANNEL_OPEN (since last: 0, network: 0s)",
    "<- NET_SSH2_MSG_CHANNEL_OPEN_CONFIRMATION (since last: 0.169, network: 0s)",
    "-> NET_SSH2_MSG_CHANNEL_REQUEST (since last: 0, network: 0s)",
    "<- NET_SSH2_MSG_CHANNEL_WINDOW_ADJUST (since last: 0.043, network: 0s)",
    "<- NET_SSH2_MSG_CHANNEL_SUCCESS (since last: 0, network: 0s)",
    "-> NET_SSH2_MSG_CHANNEL_DATA (since last: 0, network: 0s)",
    "<- NET_SSH2_MSG_CHANNEL_DATA (since last: 0.036, network: 0.036s)",
    "-> NET_SSH2_MSG_CHANNEL_DATA (since last: 0, network: 0s)",
    "<- NET_SSH2_MSG_CHANNEL_DATA (since last: 0.037, network: 0.037s)",
    "-> NET_SSH2_MSG_CHANNEL_DATA (since last: 0, network: 0s)",
    "<- NET_SSH2_MSG_CHANNEL_DATA (since last: 0.036, network: 0.036s)",
    "-> NET_SSH2_MSG_CHANNEL_DATA (since last: 0, network: 0s)",
    "<- NET_SSH2_MSG_CHANNEL_DATA (since last: 0.037, network: 0.036s)",
    "-> NET_SSH2_MSG_CHANNEL_DATA (since last: 0, network: 0s)",
    "<- NET_SSH2_MSG_CHANNEL_DATA (since last: 0.034, network: 0.034s)",
    "-> NET_SSH2_MSG_CHANNEL_OPEN (since last: 0, network: 0s)",
    "<- NET_SSH2_MSG_CHANNEL_OPEN_CONFIRMATION (since last: 0.033, network: 0.033s)",
    "-> NET_SSH2_MSG_CHANNEL_REQUEST (since last: 0, network: 0s)",
    "<- NET_SSH2_MSG_CHANNEL_SUCCESS (since last: 0.041, network: 0.041s)",
    "-> NET_SSH2_MSG_CHANNEL_REQUEST (since last: 0, network: 0s)",
    "<- NET_SSH2_MSG_CHANNEL_WINDOW_ADJUST (since last: 0.035, network: 0.035s)",
    "<- NET_SSH2_MSG_CHANNEL_SUCCESS (since last: 0, network: 0s)",
    "-> NET_SSH2_MSG_CHANNEL_DATA (since last: 0, network: 0s)",
    "<- NET_SSH2_MSG_CHANNEL_DATA (since last: 0.003, network: 0s)",
    "<- NET_SSH2_MSG_CHANNEL_DATA (since last: 0.032, network: 0s)",
    "<- NET_SSH2_MSG_CHANNEL_DATA (since last: 0.01, network: 0s)",
    "<- NET_SSH2_MSG_CHANNEL_DATA (since last: 2.3551, network: 0s)",
    "<- NET_SSH2_MSG_CHANNEL_DATA (since last: 0.249, network: 0s)",
    "<- NET_SSH2_MSG_CHANNEL_DATA (since last: 0.059, network: 0s)",
    "-> NET_SSH2_MSG_CHANNEL_DATA (since last: 17.339, network: 0s)",
    "<- NET_SSH2_MSG_CHANNEL_DATA (since last: 0.041, network: 0.041s)"
]

【问题讨论】:

  • 我还尝试将set_time_limit(240000); 增加到 4 分钟以查看它是否在我结束时超时,但这没有任何作用。

标签: php matlab phpseclib


【解决方案1】:

啊啊啊!在形象地把我的头撞到墙上之后,我注意到每次我打电话给$sftp-&gt;read() 都会有一点进步。因此,我添加了一个 do-while 循环以在读取变为黑色空时停止。成功了!

$output->read = [];
$read = true;
do {
    $read = $sftp->read('/.*@.*[$|#]/', NET_SSH2_READ_REGEX);
    $output->read[] = $read;
} while ($read);

$sftp-&gt;read() 如果没有更多内容可读取,将返回 false。

我的完整代码如下所示:

$created = $sftp->write("matlab -nodisplay -nodesktop -nosplash -logfile remote_matlab.out -r \"cd('/some_supporting_files'); some_function('/some_data_I_just_uploaded.txt'); exit;\"\r\n");

$output->read = [];
$read = true;
do {
    $read = $sftp->read('/.*@.*[$|#]/', NET_SSH2_READ_REGEX);
    $output->read[] = $read;
} while ($read);

if(!$created){
 //continue your script
}

我仍然无法使用$sftp-&gt;exec()

虽然上述解决方案有效,但如果花费太长时间而没有提供 $sftp->read() 读取的内容,它就会停止工作。我仍然希望有人能以更强大的方式解决这个问题。

【讨论】:

  • 如果您必须多次执行$sftp-&gt;read('/.*@.*[$|#]/', NET_SSH2_READ_REGEX),那么您的正则表达式似乎可以从一些改进中受益——它多次返回,因为它多次匹配正则表达式。至于$sftp-&gt;exec()...试试$sftp-&gt;enablePTY()。它使 exec() 的行为有所不同:phpseclib.sourceforge.net/ssh/pty.html
  • 我尝试将 read 的值设置为类似 $sftp-&gt;read('UniqueString') 的值,但没有成功。不过,感谢您的反馈,这无疑为我指明了另一个方向。
  • 接下来我要做的是启用日志记录(define('NET_SSH2_LOGGING', 2),设置一个非常大的超时时间(或将其设置为 0),然后执行$sftp-&gt;getLog() 看看我得到了什么.也许它在屏幕上看起来一样,但实际上可能并非如此。就像你正在取回 ANSI 转义码并且没有意识到它因为控制台本质上隐藏了它们。如果你需要任何帮助发布日志到pastebin.org,我可以看看。
  • @neubert 我正在使用 Net_SFTP,所以 define('NET_SSH2_LOGGING', 2) 似乎没有做任何事情。我之前设置了define('NET_SFTP_LOGGING', NET_SFTP_LOG_SIMPLE),但并没有那么有用。你能解释一下如何查看 ANSI 转义码吗?我正在网络浏览器中打印响应,但看不到任何异常。
  • Net_SFTP 扩展了 Net_SSH2,SFTP 在 SSH2 上运行一层。 IE。 SSH2 日志包含 SFTP 日志,但反之则不然。就像 TCP 日志如何包含 HTTP 日志一样,但反之则不然。所以,基本上,define('NET_SSH2_LOGGING', 2) 应该可以工作。它对应于NET_SSH2_LOG_COMPLEX。我只是告诉人们使用数字 2 而不是常量,因为我不希望人们在包含 Net/SSH2.php 之前尝试将 NET_SSH2_LOGGING 设置为常量。如果你做第二个没关系。
猜你喜欢
  • 2021-10-25
  • 2020-02-05
  • 1970-01-01
  • 2021-05-22
  • 1970-01-01
  • 1970-01-01
  • 2021-02-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多