使用 sftp 和 ssh2 的 fopen 出现分段错误

问题描述 投票:0回答:5

我有一个在 AWS 上运行的 php 系统,以及一个使用 shh2sftp 在外部服务器上上传 xlsx 文件的类。 这段代码工作正常,直到上次升级 aws 包 openssh-clients-6.6.1p1-31.62openssh-server-6.6.1p1-31.62,此时我在 fopen 期间遇到了 segfault。 Fopen 在外部服务器上创建一个文件。 代码在这里:

$stream = @fopen("ssh2.sftp://$this->sftp$remote_file", 'w');

然后我使用 $stream 写入内容,但代码由于段错误而停止在 fopen 上。 我没有找到任何关于这个问题的信息,我认为问题是opnessh的新升级,因为php代码没有改变。 有什么想法吗?

php amazon-web-services ssh segmentation-fault sftp
5个回答
17
投票

在 StackOverflow 上找到答案: https://stackoverflow.com/a/40972584/2520795

看来自从这个 PHP 更新以来,你必须用

ssh2_sftp()
包围你的主机部分(
intval()
的结果):

$handle = opendir("ssh2.sftp://".intval($sftp)."/path/to/directory");

在我的例子中,有一个

fopen
而不是
opendir
,但解决方案是相同的。


6
投票

如果您关闭与

intval($sftp)
的连接,即使使用
ssh2_disconnect()
解决方案,您也可能会遇到“分段错误”问题。正确的解决方案是在通过
unset($sftp)
$sftp = null
关闭 SSH2 连接之前关闭 SFTP 连接。这是我读取远程文件的完整工作示例:

if (!$ssh2_connection = ssh2_connect($host, $port)) {
    die("Failed to connect\n");
}
if (!ssh2_auth_password($ssh2_connection, $username, $password)) {
    die("Failed to login\n");
}
if (!$sftp_connection = ssh2_sftp($ssh2_connection)) {
    die("Failed to open SFTP session\n");
}
if (!$fh = fopen("ssh2.sftp://".intval($sftp_connection).$path, 'r')) {
    die("Failed to open file\n");
}
while (($s = fgets($fh)) !== false) {
    echo $s;
}
fclose($fh);
unset($sftp_connection);
if (!ssh2_disconnect($ssh2_connection)) {
    die("Failed to disconnect\n");
}

附注此外,您可能会看到类似以下内容,而不是“分段错误”:

php:channel.c:2570:_libssh2_channel_free:断言“会话”失败。

已中止

我的解决方案解决了这个问题。


3
投票

在我们的例子中,intval() 没有解决分段错误。然而,改变通话格式确实有效:

fopen("ssh2.sftp://{$username}:{$password}@{$host}:{$port}/{$absolutePath}/{$filename}", 'w');

1
投票

我有同样的错误,但我发现了这个 PHP bug (参见帖子:[2016-12-15 09:47 UTC] by ovoelker at wavecon dot de)

  1. 添加php5-dev用于编译pecl模块
  2. 重新安装 ssh2 pecl 模块。
  3. 重启apache即可正常工作

0
投票
在我的情况(php8)中,在使用

$dir = dir(...)

 函数而不调用 
$dir->close();
 后,
ssh2 在关闭期间导致了段错误。我认为如果使用
opendir()
,这也是相同的行为。

© www.soinside.com 2019 - 2024. All rights reserved.