2

我需要编写一个脚本,每天晚上作为 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]:在第 17 行 /path_to_script/sftp-test.php 的服务器配置中禁用 URL 文件访问

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

3/destination_directory_on_server/test.csv)

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

4

6 回答 6

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 的手册页以了解用法

于 2010-02-23T12:05:11.800 回答
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

谢谢!

于 2010-02-24T12:43:33.510 回答
1

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

于 2011-02-25T05:49:00.067 回答
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 挂载共享,然后将其用作普通文件夹
于 2010-02-23T11:51:41.770 回答
0

这不适用于您服务器上的 PHP,因为您的 php.ini 已禁用远程包装器

allow_url_fopen 布尔值

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

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

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

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

于 2010-02-23T11:54:44.490 回答
0

尝试如下(外壳)

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
于 2019-01-28T06:39:49.290 回答