当前位置:Linux教程 - Linux - 如何自动通过FTP下载文件

如何自动通过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公报