【问题标题】:Transfer files using SFTP and either PHP or shell/terminal script使用 SFTP 和 PHP 或 shell/终端脚本传输文件
【发布时间】:2011-01-20 00:57:51
【问题描述】:

我需要编写一个脚本,每天晚上作为 cron 作业运行,通过 sftp 将一些报告文件传输到另一台服务器。

报告文件每晚使用另一个 cron 创建,格式为“support_[date].csv”和“download_[date].csv”。

我想知道您是否对如何执行以下操作有任何指示:

  1. 查找最近 [日期] 创建的 2 个文件
  2. 使用 SFTP 将这些文件复制到另一台服务器

我已经尝试了几个使用 ssh2 扩展的 PHP 脚本,但无济于事。有没有办法使用shell脚本来做到这一点?老实说,这不是我非常熟悉的东西(因此最初沿着 PHP 路线走)

这是我的一个 PHP 脚本,它不起作用:

$src = 'test.csv';

$filename = 'test.csv';
$dest = '/destination_directory_on_server/'.$filename;

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

// Create SFTP session
$sftp = ssh2_sftp($connection);

$sftpStream = fopen('ssh2.sftp://'.$sftp.$dest, 'w');

try {
       
            if (!$sftpStream) {
                throw new Exception("Could not open remote file: $dest<br>");
            }
           
            $data_to_send = file_get_contents($src);
           
            if ($data_to_send === false) {
                throw new Exception("Could not open local file: $src.<br>");
            }
           
            if (fwrite($sftpStream, $data_to_send) === false) {
                throw new Exception("Could not send data from file: $src.<br>");
            } else {
                //Upload was successful, post-upload actions go here...
            }
           
            fclose($sftpStream);
                           
        } catch (Exception $e) {
           
            //error_log('Exception: ' . $e->getMessage());
           echo 'Exception: ' . $e->getMessage();
            if($sftpStream) {fclose($sftpStream);}
            
        }

这是我收到的错误消息:

警告:fopen() [function.fopen]: URL 文件访问在服务器中被禁用 配置在 /path_to_script/sftp-test.php 上线 17

警告:fopen(ssh2.sftp://Resource id

3/destination_directory_on_server/test.csv)

[function.fopen]:打开失败 流:可能没有合适的包装器 在 /path_to_script/sftp-test.php 中找到 在第 17 行异常:无法打开 远程文件: /destination_directory_on_server/test.csv

【问题讨论】:

    标签: php ssh cron sftp


    【解决方案1】:

    答案就在那里,在错误信息中:

    警告:fopen() [function.fopen]:服务器配置中禁用 URL 文件访问

    表示在服务器配置中禁用通过 URL 包装器进行文件访问。

    检查您的 PHP 配置,尤其是 allow_url_fopen。 PHP 文档说“出于安全原因,此设置只能在 php.ini 中设置”,因此请在此处查看。

    另见fopen:“如果 PHP 决定文件名指定了一个注册协议,并且该协议注册为网络 URL,PHP 将检查以确保启用 allow_url_fopen。如果它被关闭,PHP 将发出警告, fopen 调用将失败。”据我所知,这正是那里正在发生的事情。

    如果您不能或不会启用allow_url_fopen,您仍有一些选择:

    • 直接调用sftp
    • 使用 sshfs 挂载共享,然后将其用作普通文件夹

    【讨论】:

    • 谢谢皮斯克沃尔。由于上述安全原因,我的主机不会启用 allow_url_fopen 。因此,当您说“直接调用 sftp”时,您指的是 shell 脚本吗?因为我在那个领域有点新手...... :) 任何指针?
    • @WastedSpace: ghostdog74 的回答有一个很好的例子。
    【解决方案2】:

    这不适用于您服务器上的 PHP,因为您的 php.ini 有 disabled remote wrappers

    allow_url_fopen 布尔值

    此选项启用可识别 URL 的 fopen 包装器,该包装器可以访问 URL 对象(如文件)。为使用 ftp 或 http 协议访问远程文件提供了默认包装器,一些扩展(如 zlib)可能会注册额外的包装器。

    注意:出于安全原因,此设置只能在 php.ini 中设置。

    但是,您可以简单地让您的 cron 作业调用直接使用 sftprsync 的 shell 脚本。您不必使用 PHP 来执行此操作。

    我投票将其移至 ServerFault 以获得对 shell 脚本的更好支持。

    【讨论】:

    • 谢谢戈登。由于上述安全原因,我的主机不会启用 allow_url_fopen 。在 shell 脚本中使用 sftp 的任何指针?那个部门的新手!
    • @WasterSpace 对不起,我也不是 shell 脚本专家,这就是为什么我建议将问题移至 SF。不过,下面@ghostdog 的答案看起来很有用。
    【解决方案3】:

    使用终端查找文件的最新日期,您可以使用 ls -1tr 。然后使用 scp(不是 sftp)复制/传输文件 例如,

    #!/bin/bash
    latest_download=$(ls -1tr download*csv | tail -1)
    latest_support=$(ls -1tr support*csv | tail -1)
    scp $latest_download user@somehost.com:somedir  # syntax from memory, check man page for correct syntax
    scp $latest_support user@somehost.com:somedir
    

    查看 scp 的手册页了解使用情况

    【讨论】:

    • 向 ghostdog74 致敬!设法让它工作,但使用 sftp。首先,我设法设置了密钥身份验证,然后部分使用 ghostdog74 的脚本,我做到了这一点,而且效果很好! cd /directorywithfilesin latest_download=$(ls -1tr download* | tail -1) latest_support=$(ls -1tr support* | tail -1) sftp username@example.com
    【解决方案4】:

    向 ghostdog74 致敬!设法让它工作,但使用 sftp。

    首先我设法设置了密钥身份验证,然后部分使用了 ghostdog74 的脚本,我做到了这一点,而且效果很好!

    cd /directorywithfilesin
    latest_download=$(ls -1tr download* | tail -1)
    latest_support=$(ls -1tr support* | tail -1)
    sftp username@example.com <<EOF
    cd /dir_to_copy_to
    put $latest_download
    put $latest_support
    EOF
    

    谢谢!

    【讨论】:

    • 您可以编辑自己的问题并将更新后的答案放在那里。
    【解决方案5】:

    ghostdog74 方法的其他问题之一是它是不可移植的。我的建议是使用 phpseclib,pure PHP SFTP implementation

    【讨论】:

      【解决方案6】:

      尝试如下(Shell)

      SFTP=<sftp path>
      KEY_FILE=<your key>
      USERNAME=<remote username>
      SERVER =<remote server>
      REMOTE_DIR=<remote location>
      APP_HOME =<App location>
      FILENAME=<file name>
      
      ${SFTP} -o IdentityFile=${KEY_FILE} ${USERNAME}@${SERVER} <<_COMMAND
      lcd ${APP_HOME}
      cd ${REMOTE_DIR}
      put ${FILENAME}
      bye
      _COMMAND
      

      【讨论】:

        猜你喜欢
        • 2020-12-15
        • 1970-01-01
        • 2023-03-31
        • 2019-11-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-09-29
        相关资源
        最近更新 更多