我们有一个服务器,另一个脚本每天都在其中进行 sFTP 和下载文件。
问题:是否可以检测到文件已下载,然后在完成后自动存档文件?
澄清一下 - 我们托管文件,其他人来下载它。
这是他们使用的脚本:
let $command = 'sftp -b /usr/tmp/file.sftp someuser@myserver'
show 'FTP command is ' $command
call system using $command #status
##file.sftp##
# Set local directory on PeopleSoft server
lcd /var/tmp
# Set remote directory on the remote server
cd ar/in
# Transfer all remote files to PeopleSoft
get file.dat
get file2.dat
# quit the session
bye
答案1
我可以想到 3 种途径可以为您提供解决方案。
1.自定义sftp子系统
您可以sftp-server
通过包装守护进程sshd_config
并用您自己的脚本“覆盖”它,然后该脚本可以拦截sftp-server
正在执行的操作,然后在您看到文件已下载时采取行动。覆盖默认值sftp-server
很sshd_config
容易:
Subsystem sftp /usr/local/bin/sftp-server
弄清楚在包装器脚本中要做什么将是困难的部分/usr/local/bin/sftp-server
。在:
#!/bin/sh
# ...do something...
chroot /my/secret/stuff /usr/libexec/openssh/sftp-server
# ...do something...
2.查看日志
如果您打开调试,sftp-sever
您可以让它显示文件打开/关闭以及从 SFTP 服务器读取/写入文件的日志。您可以编写一个守护程序/脚本来监视这些日志,然后在需要时备份文件。有关如何实现这一目标的更多详细信息已部分包含在我对此 U&L Q&A 的回答中:SFTP 中的活动日志记录级别以及这篇博客文章中的标题为:SFTP 文件传输会话活动日志记录。
SFTP 日志可以增强,如下所示:
Sep 16 16:07:19 localhost sftpd-wrapper[4471]: user sftp1 session start from 172.16.221.1
Sep 16 16:07:19 localhost sftp-server[4472]: session opened for local user sftp1 from [172.16.221.1]
Sep 16 16:07:40 localhost sftp-server[4472]: opendir "/home/sftp1"
Sep 16 16:07:40 localhost sftp-server[4472]: closedir "/home/sftp1"
Sep 16 16:07:46 localhost sftp-server[4472]: open "/home/sftp1/transactions.xml" flags WRITE,CREATE,TRUNCATE mode 0644
Sep 16 16:07:51 localhost sftp-server[4472]: close "/home/sftp1/transactions.xml" bytes read 0 written 192062308
Sep 16 16:07:54 localhost sftp-server[4472]: session closed for local user sftp1 from [172.16.221.1]
然后,您需要开发一个守护程序/脚本来监视打开/关闭事件对的日志。这些代表已完成的文件传输。您还可以使用 syslog,它可以监视“CLOSE”日志事件,并可用于执行传输文件的复制。
3. 英克朗
你可以利用通知每次访问文件时 Linux 内核都会产生的事件。有一个服务叫做英克朗其工作原理与 Cron 类似。 Cron 根据时间工作,而 Incron 根据文件事件工作。因此,您可以设置一个 Incron 条目来监视您的 SFTP 上传目录,并且只要检测到特定文件事件,就复制该文件。
看看inotify 手册页用于描述各种事件。我相信您会想要查看read()
( IN_ACCESS
) 后跟close()
( IN_CLOSE_WRITE
)。这些文件适用于从 SFTP 服务器复制的文件。
Incron 规则如下所示:
<directory> <file change mask> <command or action> options
/var/www/html IN_CREATE /root/scripts/backup.sh
/sales IN_DELETE /root/scripts/sync.sh
/var/named/chroot/var/master IN_CREATE,IN_ATTRIB,IN_MODIFY /sbin/rndc reload
这篇文章的标题是:Linux incrond inotify:监视目录的更改并采取行动如果您想尝试使用此选项,则会显示更多所需的详细信息。
答案2
配置 SSH 服务器来记录活动,然后您可以解析日志以了解是否已下载此类文件。
要启用日志记录附加-l INFO
到文件中的 sftp 子系统行/etc/ssh/sshd_config
,它应该类似于(路径可能因发行版而异,我使用的是 SuSE 11):
Subsystem sftp /usr/lib64/ssh/sftp-server -l INFO
现在 sftp 会话将被登录/var/log/messages
。
这是 sftp 下载的文件的日志:
Dec 3 08:42:02 $HOSTNAME sftp-server[$PID]: session opened for local user user from [192.168.0.10]
Dec 3 08:42:03 $HOSTNAME sftp-server[$PID]: opendir "/home/user"
Dec 3 08:42:03 $HOSTNAME sftp-server[$PID]: closedir "/home/user"
Dec 3 08:42:18 $HOSTNAME sftp-server[$PID]: open "/home/user/file" flags READ mode 0666
Dec 3 08:42:19 $HOSTNAME sftp-server[$PID]: close "/home/user/file" bytes read 48843 written 0
现在您可以解析该文件以了解该文件是否已被访问,例如:
#!/bin/bash
grep sftp /var/log/messages | grep -q $FILENAME
if [ $? -eq 0 ]
do something
else
do other thing
fi
如何启用 SFTP 日志记录:https://serverfault.com/questions/73319/sftp-logging-is-there-a-way
答案3
如果您知道路径和名称,那么您可以执行此操作
if [ -f $filename ];
then
archive
else
echo ""
fi
但是您没有添加任何此类信息。