使用SFTP和PHP或shell / terminal脚本传输文件

时间:2010-02-23 11:45:21

标签: php ssh cron sftp

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

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

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

  1. 查找最新[日期]
  2. 上创建的2个文件
  3. 使用SFTP将这些文件复制到另一台服务器
  4. 我尝试了几个使用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://资源ID

         

    3 / destination_directory_on_server / test.csv)

         

    [function.fopen]:无法打开   stream:没有合适的包装器   在/path_to_script/sftp-test.php中找到   第17行例外:无法打开   远程文件:   /destination_directory_on_server/test.csv

6 个答案:

答案 0 :(得分: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的手册页以了解用法

答案 1 :(得分:2)

很多人对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

谢谢!

答案 2 :(得分:1)

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

答案 3 :(得分:0)

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

警告: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挂载共享,然后将其用作普通文件夹

答案 4 :(得分:0)

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

  

allow_url_fopen boolean

     

此选项启用支持URL的fopen包装器,以便访问类似文件的URL对象。提供了使用ftp或http协议访问远程文件的默认包装器,像zlib这样的扩展可能会注册其他包装器。

     

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

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

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

答案 5 :(得分:0)

尝试以下操作(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