如何自动通过FTP下载文件
by Manuel Arturo Izquierdo 翻译:gaia
--------------------------------------------------------------------------------
Internet不愧是广阔的信息海洋,可要想通过有限的带宽传输大量数据绝对是一种痛苦经历.就说我自己吧.我在哥伦比亚国家天文台工作,我们的局域网接到大学的ATM主干网上.可惜与外界的联系全靠一条带宽只有64K的线路.白天,网上有500多个用户可真够让人头疼的,因为网络速度慢得难以忍受.夜里就不一样了.校园里没有人,所以传输速率还算让人满意.这时你可以轻松下载大量数据(比如,整个Linux发行套件).不过, 既然我们都是血肉之躯,总在计算机旁边熬夜也不是个办法.于是有了个想法:编个小程序, 让计算机干活,我们睡觉.您该问了:怎么才能让Linux完成这项任务?看完我的文章您就明白了!
在这篇文章中,我只讨论了ftp连接,还没有做http方面的工作.如果您有好主意,请告诉我.
最先闪过的念头就是:利用at命令,在指定时间执行所需的操作.咱们想想一次简单的ftp会话是怎么进行的:(粗体字是用户键入的命令)
bash$ ftp anyserver.anywhere.net
Connected to anyserver.anywhere.net.
220 anyserver FTP server (Version wu-2.4(1) Tue Aug 8 15:50:43 CDT 1995)
ready.
Name (anyserver:theuser): anonymous
331 Guest login ok, send your complete e-mail address as password.
Password:(an e-mail address)
230 Guest login ok, access restrictions apply.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> cd pub
ftp> bin
ftp> get anyfile.tar.gz
150 Opening BINARY mode data connection for anyfile.tar.gz (3217 bytes).
226 Transfer complete.
3217 bytes received in 0.0402 secs (78 Kbytes/sec)
ftp> bye
221 Goodbye.
bash$
你可以写一个简单的shell脚本,里面包括at命令要执行的操作步骤.为了在shell脚本中执行ftp的内部命令,可以利用一种shell语法性质,即能在shell脚本中嵌入一些假托是来自标准输入的内容.这叫作\"here\"文档:
#! /bin/sh
echo This will use a \"here\" document to embed ftp commands in this script
# Begin of \"here\" document
ftp <<**
open anyserver.anywhere.net
anonymous
[email protected]
cd pub
bin
get anyfile.tar.gz
bye
**
# End of \"here\" document
echo ftp transfer ended.
注意,**字符串之间的所有内容将被传送给ftp,就象是被用户键入的一样.所以这个脚本应该打开一个到anyserver.anynet.net的ftp连接,以anonymous登录,把[email protected] 作为口令,以二进制传输方式取回位于pub目录的anyfile.tar.gz 文件.看起来这个脚本没有问题,可实际上却不能工作.为什么呢?问题就在,ftp程序不接受通过\"here\"文档送来的用户名和口令;在这种情况下ftp将把anonymous和[email protected]作为\"Invalid command\"处理. 显然,由于没有送去用户名和口令,FTP服务器将拒绝这一请求.
其实窍门就在ftp程序使用的一个隐藏文件,名为~/.netrc;它必须位于你的主目录下.这个文件包含了ftp登录到某一系统中所需要的信息,由三行文本组成:
machine anyserver.anynet.net
login anonymous
password [email protected]
如果使用私人帐号进行ftp连接,password项必须是相应帐号的口令,而不能像匿名ftp那样用e-mail 地址.这也许会留下安全漏洞,所以除用户本人之外,其他人不能有~/.netrc的读,写和执行权限. 用 chmod命令 可以很容易地实现:
chmod go-rwx .netrc
现在,我们的脚本变成这样:
#! /bin/sh
echo This will use a \"here\" document to embed ftp commands in this script
# Begin of \"here\" document
ftp <<**
open anyserver.anywhere.net
cd pub
bin
get anyfile.tar.gz
bye
**
# End of \"here\" document
echo ftp transfer ended.
ftp会从 ~/.netrc文件中抽取登录名及口令信息,并实现连接.假如我们给这个脚本起名叫getdata, (并且用chmod ugo+x getdata 使它可执行),我们就可以设定它在指定时间执行:
bash$ at 1:00 am
getdata
(control-D)
Job 70 will be executed using /bin/sh
bash$
早晨你来的时候,想要的数据就会在你的机器里了!
另一个使用这个脚本的好办法是:
bash$ nohup getdata &
[2] 131
bash$ nohup: appending output to \nohup.out\
bash$
nohup允许被它执行的那个进程(本例中是getdata)在用户退出后仍能运行.所以你可以在后台下载一堆文件而自己干别的事,或者logout而不会杀死ftp子进程.
简而言之,你可以按以下步骤一步步操作:
把服务器名,用户(anonymous)和口令信息写进~/.netrc 文件
确认~/.netrc文件的权限为-rwx------
按以下框架写一个脚本文件:
#! /bin/sh
ftp <<**
open (FTP服务器名)
(要执行的ftp命令序列...)
bye
**
赋予脚本可执行权限:chmod ugo+x scriptname
设定执行时间:
at 1:00 am
脚本文件名
(control-D)
现在完事大吉了!
此外,你还可以给这个脚本添上更多功能,让它自动更新 ~/.netrc文件,并产生一个日志文件记录ftp花了多少时间:
#!/bin/sh
# Makes a backup of the old ~/.netrc file
cp $HOME/.netrc $HOME/netrc.bak
# Configures a new ~/.netrc
rm $HOME/.netrc
echo machine anyserver.anywhere.net > $HOME/.netrc
echo login anonymous >> $HOME/.netrc
echo password [email protected] >> $HOME/.netrc
chmod go-rwx $HOME/.netrc
echo scriptname log file > scriptname.log
echo Begin conection at: >> scriptname.log
date >> scriptname.log
ftp -i<<**
open anyserver.anywhere.net
bin
cd pub
get afile.tar.gz
get bfile.tar.gz
bye
**
echo End conection at: >> scriptname.log
date >> scriptname.log
# End of scriptname script
您还可以从ftp帮助手册里学到关于ftp内部命令的更多的知识.
发布人:netbull 来自:Linux公报