lftp获取FTP Server端最新文件
最近解一个bug,要频繁编译和烧录FW,每次都要将image从远程的FTP server手动copy到本地,然后使用tftp进行烧录,实在不胜其烦。虽然上一篇简单实用的tftp烧录image脚本提高了烧录效率,但是每次将image拷贝到本地也是麻烦。
这次,我依旧想到了WSL, 使用shell脚本还是更加方便快捷,思路很简单,检查server端的最新文件,得到文件名后使用lftp下载到本地。
获取最新文件
FTP Server文件存储方式是将每天的新数据归档到以当日日期命名的文件夹中,如今天20200430
➜ lftp -u "username,password" ftp://1.2.3.4
lftp username@1.2.3.4:~> ls
04-27-20 02:03PM <DIR> 20200427
04-29-20 05:36PM <DIR> 20200429
04-30-20 01:11PM <DIR> 20200430
lftp username@1.2.3.4:/> cd 20200430
lftp username@1.2.3.4:/20200430> ls
04-30-20 08:45AM 25165953 20200430084545-FW-V1.2.1.4.img
04-30-20 09:09AM 25165953 20200430090947-FW-V1.2.1.4.img
04-30-20 10:04AM 25165953 20200430100405-FW-V1.2.1.4.img
04-30-20 11:02AM 25165953 20200430110247-FW-V1.2.1.4.img
04-30-20 01:11PM 25165953 20200430131110-FW-V1.2.1.4.img
lftp username@1.2.3.4:/20200430> exit
➜
所以获取当日文件列表时需要先进入目录,然后ls并将结果存到本地tmp文件
dir=$(date '+%Y%m%d')
lftp -u "$ftp_user,$ftp_pass" $ftp_host <<-EOF > $tmpfile
cd $dir
ls
EOF
由于ls结果默认以时间顺序排序,最新文件在最后一行,这就好办了,结合tail
和awk
就可以得到最新文件名。
image=$(tail -1 $tmpfile |awk '{print $4}')
知道了文件名,先看下本地有没有下载过,如果有则无需重复下载,如果没有就使用lftp
的get
指令下载到本地。
# return if $image already exist in local
[ -f $image ] && return
[ "x$image" = "x" ] && echo "no image today" && exit 1
lftp -u "$ftp_user,$ftp_pass" $ftp_host <<-EOF
cd $dir
get $image
EOF
以上就完成了最新image的获取,结合之前使用tftp
烧录image的脚本,更新shell脚本得到下面的完整代码。
完整代码
#!/bin/zsh
# download image from FTP server and burn it into router with tftp
burn()
{
tftp 192.168.1.1 <<-EOF > /dev/null
binary
put $1
EOF
}
dl_newest_image()
{
ftp_user="username"
ftp_pass="password"
ftp_host="ftp://1.2.3.4"
tmpfile=~/tmp/ftp_list
# get ftp file list of today
dir=$(date '+%Y%m%d')
lftp -u "$ftp_user,$ftp_pass" $ftp_host <<-EOF > $tmpfile
cd $dir
ls
EOF
image=$(tail -1 $tmpfile |awk '{print $4}')
# return if $image already exist in local
[ -f $image ] && return
[ "x$image" = "x" ] && echo "no image today" && exit 1
lftp -u "$ftp_user,$ftp_pass" $ftp_host <<-EOF
cd $dir
get $image
EOF
}
cd $DT/tmp/imgs/ # $DT代表Win10的Desktop, 是我.zshrc的一个环境变量
image=$1
if [ "x$1" = "x" ]; then
dl_newest_image
fi
echo "start burning $image"
burn $image
使用方法
为了方便,脚本文件名更新为bi
, burn image的意思,使用方法含带参和不带参两种。
- 带参 - 烧录指定文件
- 不带参 - 从FTP server获取最新文件并烧录
➜ bi 20200430110247-FW-V1.2.1.4.img
start burning 20200430110247-FW-V1.2.1.4.img
➜ bi
`20200430131128-RBR20-V2.7.1.8RC1-ubi4.img` at 15953920 (45%) 7.41M/s eta:2s [Receiving data]
start burning 20200430131128-RBR20-V2.7.1.8RC1-ubi4.img
Notice
- 其实使用
curl
也可以获取FTP Server的列表信息,使用wget
也可以下载FTP Server文件,但是鉴于公司网络代理环境复杂,容易莫名失败,所以还是使用lftp
; - 用户名密码不该直接放脚本内部,可以单独存到配置文件并设置好权限,然后脚本去读文件,当然啦,私人电脑忽略;
- 脚本中
<<-EOF
的-
表示忽略下面输入行每行开始的tab键,所以被EOF
包含的部分不能使用空格键替代tab键,否则会出错。
版权声明:本博客所有文章除特殊声明外,均采用 CC BY-NC 4.0 许可协议。转载请注明出处 litreily的博客!