前言
公司有几百台windows服务器每次程序更新如果是一台台拷数据只怕安排十个人一天都不一定做得完所以就必须研究个全自动更新方案来于是就想到了FTP做个主FTP站在几百台客户机上启动BAT脚本每秒检测一次如果主站有更新程序就自动下载更新几分钟内上台windows服务器都可以全自动更新程序完毕相当实用现把当初研究BAT的脚本思路贴出来希望对大批量运维人员一个方向当然批量更新服务器每个公司有它自己的解决办法这个BAT的方式不是最优的可以用shell可以用perl也可以用python等脚本解决
一FTP命令说明
在windows系统中因为FTP是一个程序如果在bat脚本中直接调用FTP的命令在执行时总会弹出命令行窗口循环在>FTP光标这所以要换种方式利用S:filename更多的命令请输入h查看
FTP登录成功后需要下载远程单个文件时使用get命令如果下载多个文件时用mget它支持通配符在使用mget时需要对每一个文件都进行选择Y/N如果想不交互的下载全部的文件可以输入一次prompt命令关闭交互方式
Mput和mget命令要注意两个问题
Ⅰ不能对目标文件指定命字在命令行上所有的文件都视做源文件
Ⅱmputmget两个命令不能对目录进行上传与下载只能对文件
ⅢPrompt每次执行一个这个命令就在on off之间循环ftp脚本开始时prompt默认为on所以一般在上传下载文件时执行一次prompt把交互式的on关掉变为off
文件的传输方式 Binary 二进制传输
Ascii ascII传输
在FTP文件传输过程中ASCII传输HTML和文本编写的文件而二进制码传输可以传送文本和非文本(执行文件压缩文件图片等)具有通用性二进制码传输速度比ASCII传输要快所以在建立bat脚本时一般输入bin命令启用二进制传输如果用ASCII模式传输非文本文件可能会显示一堆乱码如果是上传一些CGI脚本有可能将无法运行这类脚本而在浏览器上看到server error的错误
Ascii和binary模式的区别是回车换行的处理binary模式不对数据进行任何处理asci模式将回车换行转换为本机的回车字符比如Unix下是\nWindows下是\r\nMac下是\runix系统下行结束符是一个字节即十六进制的A而ms的系统是两个字节即十六进制的DA
所以当你用ascii方式从unix的ftp server下载文件时(不管是二进制或者文本文件redhat的 vsftp默认是binaryascii默认关闭)每检测到一个字节是A就会自动插入一个D所以如果你的文件是二进制文件比如可执行文件压缩包什么的就肯定不能用了如果你的文件就是unix下的文本文件你用 ascii模式是正确的要是误用了binary模式你在windows上看这个文件是没有换行的里面是一个个的黑方块
在用FTP客户端传输文件时因为这些软件都做得比较智能化它可以根据后缀自动启用传输模式所以不用担心出问题
二实例求证
环境说明上有一FTP服务器端(windows版)FTP用户名为lgh密码为该用户的根目录为D\lgh里面文件见下图sqlrar是sqlbat的压缩文件大家注意看图我等下会在后面的实例中引用这个文件把mgetgetpromptbinascii等ftp命令诠释得一清二白
实例一直接BAT调用FTP命令 ftpbatbat内容
(***大家建立bat文件不要命名为ftpbat执行时会有问题***)
复制代码 代码如下:
ftp
open
lgh
get sqlrar
bye
从图上的结果看
bat脚本直接调用xp的FTP命令是不行的
执行时H:\>ftp会一直死循环
我这里的XP系统是SP
的
其它版本的
我没有作测试
如果有不同
欢迎大家留言告之
实例二用putget上传下载单个文件
把XP机器上H:\js目录下文件flowerzip上传到FTP服务器
把FTP服务器中的sqlrar文件下载到XP机器上的H:\JS目录
ftpgetputbat内容如下
复制代码 代码如下:
@echo off
set ftpfilename=autoftpcfg
echo open >%ftpfilename%
echo lgh >>%ftpfilename%
echo >>%ftpfilename%
echo bin >>%ftpfilename%
echo lcd h:\js >>%ftpfilename%
echo get sqlrar >>%ftpfilename%
echo put flowerzip >>%ftpfilename%
echo bye >>%ftpfilename%
ftp s:%ftpfilename%
del %ftpfilename%
我们来看看结果见下面两张图从XP系统上看H盘的JS目录多了个sqlrarFTP服务器上的根目录多了个flowerzip这说明刚才的脚本完成正常的执行了达到了预期的目的
实例三用putget上传下载多个文件 在XP机器上把flowerzip复制一次改名为flowerzip
在XP机器上把把第二次实例下载的sqlrar文件删除以免影响到本次操作
在FTP服务器上把第二次实例上传的flowerzip文件删除以免影响到本次操作
把XP机器上H:\js目录下文件flowerzip 和flowerzip上传到FTP服务器
ftpgetputmanybat内容如下
复制代码 代码如下:
@echo off
set ftpfilename=autoftpcfg
echo open >%ftpfilename%
echo lgh >>%ftpfilename%
echo >>%ftpfilename%
echo bin >>%ftpfilename%
echo lcd h:\js >>%ftpfilename%
echo put flowerzip flowerzip>>%ftpfilename%
echo bye >>%ftpfilename%
ftp s:%ftpfilename%
del %ftpfilename%
到FTP服务器上查看根目录看flowerzip与flowerzip是否已成功上传从图上看只成功上传了flowerzip文件
刚那个ftpgetputmanybat脚本里
echo put flowerzip flowerzip>>%ftpfilename%
flowerzip是传输的最后一个文件是不是用put时意味着bat在处理上传时只认最后一个文件呢我们再多加个文件flowerzip来验证
在XP机器上把flowerzip复制一次改名为flowerzip
在FTP服务器上把第二次实例上传的flowerzip文件删除以免影响到本次操作
ftpgetputmanybat内容修改如下
复制代码 代码如下:
@echo off
set ftpfilename=autoftpcfg
echo open >%ftpfilename%
echo lgh >>%ftpfilename%
echo >>%ftpfilename%
echo bin >>%ftpfilename%
echo lcd h:\js >>%ftpfilename%
echo put flowerzip flowerzip flowerzip>>%ftpfilename%
echo bye >>%ftpfilename%
ftp s:%ftpfilename%
del %ftpfilename%
结果还是只成功上传了flowerzip因bat双击时执行过程会一闪而过我们看不到执行过程到命令行去执行下看到底出了什么问题
命令行执行ftpgetputmanybat脚本从执行情况看flowerzip三个文件都是put的但在传输时却只传了flowerzip真不解有知道的朋友吗?给点方向
再换个方式用通配符*试试
ftpgetputmanybat内容修改如下
复制代码 代码如下:
@echo off
set ftpfilename=autoftpcfg
echo open >%ftpfilename%
echo lgh >>%ftpfilename%
echo >>%ftpfilename%
echo bin >>%ftpfilename%
echo lcd h:\js >>%ftpfilename%
echo put flower*zip >>%ftpfilename%
echo bye >>%ftpfilename%
ftp s:%ftpfilename%
del %ftpfilename%
在FTP服务器上把上传的flower文件全部删除以免影响到本次操作
执行ftpgetputmanybat结果只有flowerzip文件上传成功了呵flowerzip文件怎么都不能上传???
其实用put传输多个文件完全可用重复的方式取代比如ftpgetputmanybat内容修改如下
复制代码 代码如下:
@echo off
set ftpfilename=autoftpcfg
echo open >%ftpfilename%
echo lgh >>%ftpfilename%
echo >>%ftpfilename%
echo bin >>%ftpfilename%
echo lcd h:\js >>%ftpfilename%
echo put flowerzip >>%ftpfilename%
echo put flowerzip >>%ftpfilename%
echo put flowerzip >>%ftpfilename%
echo bye >>%ftpfilename%
ftp s:%ftpfilename%
del %ftpfilename%
实例四用mputmget上传下载多个文件 在FTP服务器上删除有关flower的文件
ftpmgetmputmanybat内容如下:
复制代码 代码如下:
@echo off
set ftpfilename=autoftpcfg
echo open >%ftpfilename%
echo lgh >>%ftpfilename%
echo >>%ftpfilename%
echo bin >>%ftpfilename%
echo lcd h:\js >>%ftpfilename%
echo mput flowerzip flowerzip flowerzip>>%ftpfilename%
echo bye >>%ftpfilename%
ftp s:%ftpfilename%
del %ftpfilename%
双击ftpmgetmputmanybat后发现系统弹出一窗口后就卡住了停止不前
原因是用了mput命令但没有用Prompt关闭交互
ftpmgetmputmanybat内容修改如下:
复制代码 代码如下:
@echo off
set ftpfilename=autoftpcfg
echo open >%ftpfilename%
echo lgh >>%ftpfilename%
echo >>%ftpfilename%
echo Prompt >>%ftpfilename%
echo bin >>%ftpfilename%
echo lcd h:\js >>%ftpfilename%
echo mput flowerzip flowerzip flowerzip>>%ftpfilename%
echo bye >>%ftpfilename%
ftp s:%ftpfilename%
del %ftpfilename%
再次执行ftpmgetmputmanybat结果见下图
用通配符*试试
在FTP服务器上删除有关flower的文件
ftpmgetmputmanybat内容修改如下:
复制代码 代码如下:
@echo off
set ftpfilename=autoftpcfg
echo open >%ftpfilename%
echo lgh >>%ftpfilename%
echo >>%ftpfilename%
echo Prompt >>%ftpfilename%
echo bin >>%ftpfilename%
echo lcd h:\js >>%ftpfilename%
echo mput flower*zip >>%ftpfilename%
echo bye >>%ftpfilename%
ftp s:%ftpfilename%
del %ftpfilename%
照样成功上传有关flower*zip文件因为结果与上一步是一样的所以就不抓图了
实例五用ascii在windows系统间传输非文本文件 把XP电脑上的rmbjpg通过ascii传到FTP服务器的根目录
ftpgetasciibat内容修改如下:
复制代码 代码如下:
@echo off
set ftpfilename=autoftpcfg
echo open >%ftpfilename%
echo lgh >>%ftpfilename%
echo >>%ftpfilename%
echo ascii >>%ftpfilename%
echo lcd h:\js >>%ftpfilename%
echo put rmbjpg>>%ftpfilename%
echo bye >>%ftpfilename%
ftp s:%ftpfilename%
del %ftpfilename%
执行ftpgetasciibat后发现rmbjpg可以正常上传并且可以正常打开那这个现象与前面所以的ascii不能传输非文本东西有出入这是怎么回会事呢
这是因为FTP服务器是WINDOWS系统XP电脑上的bat脚本也是在windows系统上运行的所以bat在windows系统里用FTP传输文件不管是用ascii还是用binary都是可以的接下来我们再做一个实验FTP服务器选centos再测下ascii传输非文本文件问题
实例六用ascii在windows系统与linux系统间传输非文本文件
在RHEL 位系统上建立一vsftpd服务器
上面说过redhat默认启用二进制传输关闭了ascii码传输所以我们还要修改一下vsftpd的配置文件修改/etc/vsftpd/nf文件允许客户端进行ascii传输并重启vsftpd
把rmbjpg放到FTP服务器大家注意下H:\js目录下只有ftpgetasciibat文件
ftpgetasciibat文件内容修改如下
复制代码 代码如下:
@echo off
set ftpfilename=autoftpcfg
echo open >%ftpfilename%
echo ftp >>%ftpfilename%
echo redhat >>%ftpfilename%
echo asc >>%ftpfilename%
echo lcd h:\js >>%ftpfilename%
echo get rmbjpg >>%ftpfilename%
echo bye >>%ftpfilename%
ftp s:%ftpfilename%
del %ftpfilename%
执行ftpgetasciibat看结果rmbjpg文件有下载到XP电脑里双击这个文件发现图像乱码文件被破坏了都是ascii码传输惹的祸
换bin传输测试一下
在XP电脑上删除rmbjpg文件再双击ftpgetasciibat文件去从LINUX的FTP服务器下载一个rmbjpg文件
修改ftpgetasciibat把ascii改给二进制传输
复制代码 代码如下:
@echo off
set ftpfilename=autoftpcfg
echo open >%ftpfilename%
echo ftp >>%ftpfilename%
echo redhat >>%ftpfilename%
echo bin >>%ftpfilename%
echo lcd h:\js >>%ftpfilename%
echo get rmbjpg >>%ftpfilename%
echo bye >>%ftpfilename%
ftp s:%ftpfilename%
del %ftpfilename%
结果文件正常下载图像也显示正常
扩展阅读
ftp使用的内部命令如下(中括号表示可选项):
![cmd[args]]在本地机中执行交互shellexit回到ftp环境如!ls*zip
$ macroame[args]执行宏定义macroname
account[password]提供登录远程系统成功后访问系统资源所需的补充口令
append localfile[remotefile]将本地文件追加到远程系统主机若未指定远程系统文件名则使用本地文件名
ascii使用ascii类型传输方式
bell每个命令执行完毕后计算机响铃一次
bin使用二进制文件传输方式
bye退出ftp会话过程
case在使用mget时将远程主机文件名中的大写转为小写字母
cd remotedir进入远程主机目录
cdup进入远程主机目录的父目录
chmod mode filename将远程主机文件filename的存取方式设置为mode如 chmod aout
close中断与远程服务器的ftp会话(与open对应)
cr使用asscii方式传输文件时将回车换行转换为回行
delete remotefile删除远程主机文件
debug[debugvalue]设置调试方式 显示发送至远程主机的每条命令如 deb up 若设为表示取消debug
dir[remotedir][localfile]显示远程主机目录并将结果存入本地文件localfile
disconnection同close
form format将文件传输方式设置为format缺省为file方式
get remotefile[localfile] 将远程主机的文件remotefile传至本地硬盘的localfile
glob设置mdeletemgetmput的文件名扩展缺省时不扩展文件名同命令行的g参数
hash每传输字节显示一个hash符号(#)
help[cmd]显示ftp内部命令cmd的帮助信息如help get
idle[seconds]将远程服务器的休眠计时器设为[seconds]秒
image设置二进制传输方式(同binary)
lcd[dir]将本地工作目录切换至dir
ls[remotedir][localfile]显示远程目录remotedir 并存入本地文件localfile
macdef macroname定义一个宏遇到macdef下的空行时宏定义结束
mdelete[remotefile]删除远程主机文件
mdir remotefiles localfile与dir类似但可指定多个远程文件如 mdir *o*zipoutfile
mget remotefiles传输多个远程文件
mkdir dirname在远程主机中建一目录
mls remotefile localfile同nlist但可指定多个文件名
mode[modename]将文件传输方式设置为modename 缺省为stream方式
modtime filename显示远程主机文件的最后修改时间
mput localfile将多个文件传输至远程主机
newer filename 如果远程机中filename的修改时间比本地硬盘同名文件的时间更近则重传该文件
nlist[remotedir][localfile]显示远程主机目录的文件清单并存入本地硬盘的localfile
nmap[inpattern outpattern]设置文件名映射机制 使得文件传输时文件中的某些字符相互转换如nmap $$$[$$][$$]则传输文件aaa时文件名变为aa该命令特别适用于远程主机为非UNIX
机的情况
ntrans[inchars[outchars]]设置文件名字符的翻译机制如ntransR则文件名LLL将变为RRR
open host[port]建立指定ftp服务器连接可指定连接端口
passive进入被动传输方式
prompt设置多个文件传输时的交互提示
proxy ftpcmd在次要控制连接中执行一条ftp命令 该命令允许连接两个ftp服务器以在两个服务器间传输文件第一条ftp命令必须为open以首先建立两个服务器间的连接
put localfile[remotefile]将本地文件localfile传送至远程主机
pwd显示远程主机的当前工作目录
quit同bye退出ftp会话
quote argarg将参数逐字发至远程ftp服务器如quote syst
recv remotefile[localfile]同get
reget remotefile[localfile]类似于get但若localfile存在则从上次传输中断处续传
rhelp[cmdname]请求获得远程主机的帮助
rstatus[filename]若未指定文件名则显示远程主机的状态否则显示文件状态
rename[from][to]更改远程主机文件名
reset清除回答队列
restart marker从指定的标志marker处重新开始get或put如restart
rmdir dirname删除远程主机目录
runique设置文件名唯一性存储若文件存在则在原文件后加后缀等
send localfile[remotefile]同put
sendport设置PORT命令的使用
site argarg将参数作为SITE命令逐字发送至远程ftp主机
size filename显示远程主机文件大小如site idle
status显示当前ftp状态
struct[structname]将文件传输结构设置为structname 缺省时使用stream结构
sunique将远程主机文件名存储设置为唯一(与runique对应)
system显示远程主机的操作系统类型
tenex将文件传输类型设置为TENEX机的所需的类型
tick设置传输时的字节计数器
trace设置包跟蹤
type[typename]设置文件传输类型为typename缺省为ascii如type binary设置二进制传输方式
umask[newmask]将远程服务器的缺省umask设置为newmask如umask
user username[password][account]向远程主机表明自己的身份需要口令时必须输入口令如user anonymous my@email
verbose同命令行的v参数即设置详尽报告方式ftp服务器的所有响应都将显示给用户缺省为on
?[cmd]同help