簡體   English   中英

ssh2_scp_send僅在Windows上有效,但不能在linux上復制到amazon.com

[英]ssh2_scp_send works only on windows, but doesn't copy on linux to amazon.com

我有一個小腳本,可以通過ssh2庫復制文件用於php。 我在Windows上嘗試了不同版本的php,它可以按預期工作,但是當我在Linux上上傳代碼時,它無法復制文件。

注意,PHP代碼是相同的,PHP版本是相同的。 我沒有收到任何錯誤消息。 我在預設文件權限時使用此命令。 在此之前,我嘗試使用fopen,fwrite槽sftp,但在復制文件后無法對文件進行chmod設置。

這是代碼(如果有的話):

public function connect() {

    if (empty($this->ftpProps['ftpServer'])) {
        $result['errorMsg'] = 'No FTP Server Provided';
        $this->callFunc($this->callbackFunction, '<span class="error">'.$result['errorMsg'].'</span><br>'."\n");
        return $result;
    }

    $this->ftpProps['ftpServer'] = str_replace("sftp://", "", $this->ftpProps['ftpServer']);
    $this->callFunc($this->callbackFunction, 'Connecting to: <b>'.$this->ftpProps['ftpServer'].'</b>...'."\n");

    if (!function_exists('ssh2_connect')) {
        $result['errorMsg'] = 'Missing Secure Shell2 Library';
        $this->callFunc($this->callbackFunction, '<span class="error">'.$result['errorMsg'].'</span><br>'."\n");
        return $result;
    }

    $this->connection = ssh2_connect($this->ftpProps['ftpServer'], 22);
    if (empty($this->connection)) {
        $result['errorMsg'] = "Couldn't connect to ".$this->ftpProps['ftpServer'];
        $this->callFunc($this->callbackFunction, '<span class="error">'.$result['errorMsg'].'</span><br>'."\n");
        return $result;
    }
    $this->callFunc($this->callbackFunction, '<span class="successfull">Done</span><br />');

    // login
    if (empty($this->ftpProps['ftpUser'])) {
        $result['errorMsg'] = 'No FTP UserName Provided';
        $this->callFunc($this->callbackFunction, '<span class="error">'.$result['errorMsg'].'</span><br>'."\n");
        return $result;
    }

    $this->callFunc($this->callbackFunction, 'Logging in as <b>'.$this->ftpProps['ftpUser'].'</b>...'."\n");

    $this->authResult = ssh2_auth_password($this->connection, $this->ftpProps['ftpUser'], $this->ftpProps['ftpPass']);

    if (!$this->authResult) {
        $result['errorMsg'] = 'Failed to connect to '.$this->ftpProps['ftpServer'].'. Wrong credentials.';
        $this->callFunc($this->callbackFunction, '<span class="error">'.$result['errorMsg'].'</span><br>'."\n");
        return $result;
    }

    $this->callFunc($this->callbackFunction, '<span class="successfull">Done</span><br />');
    $this->callFunc($this->callbackFunction, 'Initializing SFTP subsystem of <b>'.$this->ftpProps['ftpServer'].'</b>...'."\n");

    $sftp = ssh2_sftp($this->connection);
    if (!$sftp) {
        $result['errorMsg'] = 'Failed to initialize SFTP subsystem of '.$this->ftpProps['ftpServer'];
        $this->callFunc($this->callbackFunction, '<span class="error">'.$result['errorMsg'].'</span><br>'."\n");
        return $result;
    }

    $this->callFunc($this->callbackFunction, '<span class="successfull">Done</span><br />');
    $result['message'] = 'Success';
    $result['isTestSuccessful'] = true;
    return $result;
}

//@Override
public function upload() {
    $timer = lloader()->getTimer();

    $uploadStartedOn = time();
    $connectResult = $this->connect();
    if (!empty($connectResult['errMsg'])) { return $connectResult; }

    $targetFileNames = $this->ftpProps['targetFileNames'];
    $sourceFileNames = $this->ftpProps['sourceFileNames'];

    foreach ($sourceFileNames as $nameIndex => $sourceFileName) {
        $targetFileName = $targetFileNames[$nameIndex];
        echoFlush('Uploading <b>'.$targetFileName.'</b>...');

        // use ssh2_scp_send instead fopen because of opportunity to set file mode. amazon disables chmod command
        $writeResult = ssh2_scp_send($this->connection, $sourceFileName, $this->ftpProps['destPath'].$targetFileName, 0755);
        if (!$writeResult) {
            $result['errorMsg'] = 'Failed to upload '.$targetFileName;
            $this->callFunc($this->callbackFunction, '<span class="error">'.$result['errorMsg'].'</span><br>'."\n");
            return $result;
        }
        $this->callFunc($this->callbackFunction, '<span class="successfull">Done</span><br />');
    }

    $this->callFunc($this->callbackFunction, '<span class="successfull">Done</span><br>'."\n");
    $this->callFunc($this->callbackFunction, 'The Upload Took '.$timer->getFormattedElapsedTime(time() - $uploadStartedOn).'<br>'."\n");

    $result['message'] = 'Success';
    $result['isSubmitSuccessful'] = true;
    return $result;
}

這是Linux發行版:

cat /etc/*-release
CentOS release 5.9 (Final)

php -i命令返回的一些行:

Registered PHP Streams => https, ftps, compress.zlib, compress.bzip2, php, file, data,
               http, ftp, ssh2.shell, ssh2.exec, ssh2.tunnel, ssh2.scp, ssh2.sftp, zip
Registered Stream Socket Transports => tcp, udp, unix, udg, ssl, sslv3, sslv2, tls
...
ssh2
libssh2 version => 1.2.9
banner => SSH-2.0-libssh2_1.2.9
...
Stream Wrapper support => compress.zlib://
zlib.output_compression => Off => Off
zlib.output_compression_level => -1 => -1

編輯:

我只是嘗試使用fopen / fwrite / fclose而不是ssh_scp_send並得到了相同的結果。 我完全感到困惑。 這是文件上傳的代碼:

$targetHandler = fopen("ssh2.sftp://".$this->sftp."/".$this->ftpProps['ftpDestPath'].$targetFileName, 'w');
        if (empty($targetHandler)) {
            $result['errorMsg'] = 'Failed to open '.$targetFileName;
            return $result;
        }
        $sourceHandler = @fopen($sourceFileName, "r");
        while (!feof($sourceHandler)) {
            $readBlock = fread($sourceHandler, 16384);
            $resultWrite = fwrite($targetHandler, $readBlock);
            if ($resultWrite === false) {
                $result['errorMsg'] = 'Failed to upload '.$targetFileName;
                fclose($targetHandler);
                fclose($sourceHandler);
                return $result;
            }
        }

        $chmodResult = ssh2_sftp_chmod($this->sftp, $this->ftpProps['destPath'].$targetFileName, 0755);
        if (empty($chmodResult)) {
            $result['errorMsg'] = 'Failed to chmod '.$targetFileName;
            return $result;
        }

謝謝。

編輯2:看來這是亞馬遜sftp特定的問題。 我在其他服務器上嘗試過,它在兩個平台上都可以工作。 我首先想到的是IP的某種保護。 你怎么看? 亞馬遜sftp服務器位於:productads.amazon-digital-ftp.com

看起來SSH2庫有兩個先決條件,您是否已驗證Linux是否滿足要求?

http://www.php.net/manual/zh/ssh2.requirements.php

我找到了此腳本行為的原因。 它是ssh2庫版本。 在我的本地主機和一台Linux服務器上,它是SSH-2.0-libssh2_1.4.3。 在有問題的計算機上,該庫的版本為SSH-2.0-libssh2_1.2.9。 因此,這似乎是一個庫錯誤。

我將這些帖子留給那些使用此庫且不想更改其代碼的人使用。

謝謝你的時間。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM