功能:shell脚本实现sftp自动登录并下载文件
系统环境:centos7

使用到的工具:lftp (安装方式 yum -y install lftp)
lftp:lftp 是一个功能强大的下载工具,它支持访问文件的协议: ftp, ftps, http, https, hftp, fish.(其中ftps和https需要在编译的时候包含openssl库)。llftp的界面非常想一个shell: 有命令补全,历史记录,允许多个后台任务执行等功能,使用起来非常方便。它还有书签、排队、镜像、断点续传、多进程下载等功能。
lftp下载http://rpmfind.net/linux/centos/7.9.2009/os/x86_64/Packages/lftp-4.4.8-12.el7_8.1.x86_64.rpm

lftp常用命令

登录
lftp ftp://user:password@site:port
lftp -u user:password ftp://site:port
lftp user:password@site:port
lftp site -p port -u user,password
lftp site:port -u user,password

命令

含义

ls

显示远端文件列表( !ls 显示本地文件列表 )

cd

切换远端目录(lcd 切换本地目录)

get

下载远端文件

mget

下载远端文件(可以用通配符也就是 *)

mirror

下载目录 (mirror -R 上传目录)

pget

使用多个线程来下载远端文件, 预设为五个

put

上传文件

mput

上传多个文件(支持通配符)

mv

移动远端文件(远端文件改名)

rm

删除远端文件,参数-r,递归删除文件夹

mrm

删除多个远端文件(支持通配符)

mkdir

建立远端目录

rmdir

删除远端目录

pwd

显示目前远端所在目录(lpwd 显示本地目录)

实现代码

#!/bin/bash

#sftp服务器地址
host="192.168.149.128"
#端口
port=22
sftp_user="sftp"
#密码
password="123456"

#下载到本地的目录
localDir="/tmp"
[ ! -d $localDir ] && mkdir -p $localDir
#sftp中待下载文件目录
remoteDir="/"

#要下载的文件为fileName
fileName="data.log"
lftp -u ${sftp_user},${password} sftp://${host}:${port}<<EOF
cd ${remoteDir}
lcd ${localDir} 
get $fileName
by
EOF

注意:以上代码实现了针对指定路径中的指定文件的下载,如果需要下载整个目录,需要使用lftp 中的 mirror

mirror的用法:
mirror [OPTS] [source [target]]

将源文件夹镜像到目标文件夹。如果目标文件夹以 / 结尾,原文件夹名称会被附加到目标文件夹名称之后。源和目标都可以是指向文件夹的URL。

-c,--continue 续传上次的任务
-e,--delete 删除远程目录上不存在的文件
   --delete-first 在传输新文件之前删除旧的文件
   --depth-first 进入下一层目录优先于文件传输
-s,--allow-suid 根据远程站点设置suid/sgid比特位
   --allow-chown 尝试将自己设置为文件所有者和所有组
   --ascii 使用ascii方式传输(隐含了--ignore-size)
   --ignore-time 决定是否下载时忽略时间因素
   --ignore-size 决定是否下载时忽略文件大小因素
   --only-missing 只下载缺少的文件
   --only-existing 只下载已经存在于目标文件夹中的文件
-n,--only-newer 只下载新文件(-c参数无法工作)
   --no-empty-dirs 不创建空文件夹(隐含了--depth-first)
-r,--no-recursion 不进入子文件夹
   --no-symlinks 不创建符号链接
-p,--no-perms 不设置文件权限
   --no-umask 不使用文件预设权限
-R,--reverse 反向镜像(上传文件)
-L,--dereference 将符号链接作为文件下载
-N,--newer-than=SPEC 只下载比指定时间晚的文件
   --on-change=CMD 只要有文件或文件夹存在差异就执行命令CMD
   --older-than=SPEC 只下载比指定时间早的文件
   --size-range=RANGE 只下载大小在指定区间上的文件
-P,--parallel[=N] 并行下载N个文件
   --use-pget[-n=N] 使用pget传输每个文件
   --loop 循环知道找不到差异
-i RX,--include RX 包括相匹配的文件
-x RX,--exclude RX 不包括相匹配的文件
-I GP,--include-glob GP 包括相匹配的文件
-X GP,--exclude-glob GP 不包括相匹配的文件
-v,--verbose[=level] 冗长操作
   --log=FILE 将执行的lftp命令写入文件FILE
   --script=FILE 将lftp命令写入文件FILE,但不执行
   --just-print, --dry-run 与--script=-相同
   --use-cache 使用缓存目录列表
--Remove-source-files 传输完成后删除源文件
-a 与--allow-chown --allow-suid --no-umask相同

注意
当使用 -R 参数时,第一个目录为本地目录,第二个为远程目录
如果第二项没有填写,则采用第一个个目录的名称
如果两项都没填写,则采用当前的本地和远程目录

RX是扩展的正则表达式,具体语法可参考egrep命令。

GP是通配符规则,比如*.zip。

包含和不包含选项可以被多次使用。符合以下规则之一的文件将被镜像传输:(1)符合包含规则而不符合之后的不包含规则;(2)不符合任何规则,但第一条为不包含规则。目录匹配时包括结尾的/。

注意:符号链接(软链接)不会被传输到远程服务器上,因为无法被FTP协议传输。要上传链接指向的文件,请使用mirror -RL命令(将符号链接视为普通文件)。

对于–newer-than选项,你可以使用文件或时间作为参数。时间参数的格式同at命令,如now-7days、week age等。如果指定为文件,将采用文件的修改时间。

同步sftp文件示例:

#!/bin/bash

#sftp服务器地址
host="192.168.149.128"
#端口
port=22
sftp_user="sftp"
#密码
password="123456"

#下载到本地的目录
localDir="/data/logs/sftp_logs"
[ ! -d $localDir ] && mkdir -p $localDir
#sftp中待下载的文件目录
remoteDir1="/oslog"
remoteDir2="/data"

lftp -u ${sftp_user},${password} sftp://${host}:${port}<<EOF
cd /
lcd ${localDir} 
mirror ${remoteDir1}
mirror ${remoteDir2}
by
EOF

将本地文件上传到sftp中

#!/bin/bash

#sftp服务器地址
host="192.168.149.128"
#端口
port=22
sftp_user="sftp"
#密码
password="123456"

#本地的目录
localDir="/data/test/"
localFile="/data/test/*.zip"

#sftp中的目录
remoteDir="/file"


lftp -u ${sftp_user},${password} sftp://${host}:${port}<<EOF
mput ${localFile} #将本地localFile文件上传到sftp中(支持通配符)
mirror -R  ${localDir} ${remoteDir} #将本地localDir中的文件或目录上传到sftp服务端的remoteDire中
mirror -R -I b*.zip ${localDir} ${remoteDir} #将本地localDir中的b.*zip文件上传到sftp remoteDire中
mirror -R --only-newer --only-missing -I b*.zip ${localDir} ${remoteDir} #将本地localDir中的b.*zip文件上传到sftp remoteDire中(只上传新文件,貌似默认选项就是)
by
EOF