📄 ch18_03.htm
字号:
<HTML><HEAD><TITLE>Recipe 18.2. Being an FTP Client (Perl Cookbook)</TITLE><METANAME="DC.title"CONTENT="Perl Cookbook"><METANAME="DC.creator"CONTENT="Tom Christiansen & Nathan Torkington"><METANAME="DC.publisher"CONTENT="O'Reilly & Associates, Inc."><METANAME="DC.date"CONTENT="1999-07-02T01:44:59Z"><METANAME="DC.type"CONTENT="Text.Monograph"><METANAME="DC.format"CONTENT="text/html"SCHEME="MIME"><METANAME="DC.source"CONTENT="1-56592-243-3"SCHEME="ISBN"><METANAME="DC.language"CONTENT="en-US"><METANAME="generator"CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"><LINKREV="made"HREF="mailto:online-books@oreilly.com"TITLE="Online Books Comments"><LINKREL="up"HREF="ch18_01.htm"TITLE="18. Internet Services"><LINKREL="prev"HREF="ch18_02.htm"TITLE="18.1. Simple DNS Lookups"><LINKREL="next"HREF="ch18_04.htm"TITLE="18.3. Sending Mail"></HEAD><BODYBGCOLOR="#FFFFFF"><img alt="Book Home" border="0" src="gifs/smbanner.gif" usemap="#banner-map" /><map name="banner-map"><area shape="rect" coords="1,-2,616,66" href="index.htm" alt="Perl Cookbook"><area shape="rect" coords="629,-11,726,25" href="jobjects/fsearch.htm" alt="Search this book" /></map><div class="navbar"><p><TABLEWIDTH="684"BORDER="0"CELLSPACING="0"CELLPADDING="0"><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch18_02.htm"TITLE="18.1. Simple DNS Lookups"><IMGSRC="../gifs/txtpreva.gif"ALT="Previous: 18.1. Simple DNS Lookups"BORDER="0"></A></TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="228"><B><FONTFACE="ARIEL,HELVETICA,HELV,SANSERIF"SIZE="-1"><ACLASS="chapter"REL="up"HREF="ch18_01.htm"TITLE="18. Internet Services"></A></FONT></B></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch18_04.htm"TITLE="18.3. Sending Mail"><IMGSRC="../gifs/txtnexta.gif"ALT="Next: 18.3. Sending Mail"BORDER="0"></A></TD></TR></TABLE></DIV><DIVCLASS="sect1"><H2CLASS="sect1"><ACLASS="title"NAME="ch18-chap18_being_0">18.2. Being an FTP Client</A></H2><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch18-pgfId-255">Problem</A></H3><PCLASS="para"><ACLASS="indexterm"NAME="ch18-idx-1000004287-0"></A><ACLASS="indexterm"NAME="ch18-idx-1000004287-1"></A><ACLASS="indexterm"NAME="ch18-idx-1000004287-2"></A><ACLASS="indexterm"NAME="ch18-idx-1000004287-3"></A>You want to connect to an FTP server and get or put files. You might want to automate the one-time transfer of many files or automatically mirror an entire section of an FTP server, for example.</P></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch18-pgfId-261">Solution</A></H3><PCLASS="para">Use the CPAN module Net::FTP:</P><PRECLASS="programlisting">use Net::FTP;$ftp = Net::FTP->new("ftp.host.com") or die "Can't connect: $@\n";$ftp->login($username, $password) or die "Couldn't login\n";$ftp->cwd($directory) or die "Couldn't change directory\n";$ftp->get($filename) or die "Couldn't get $filename\n";$ftp->put($filename) or die "Couldn't put $filename\n";</PRE></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch18-pgfId-281">Discussion</A></H3><PCLASS="para">Using the Net::FTP module is a three-part process: <EMCLASS="emphasis">connect</EM> to a server, identify and <EMCLASS="emphasis">authenticate</EM> yourself, and <EMCLASS="emphasis">transfer</EM> files. All interaction with the FTP server happens through method calls on a Net::FTP object. If an error occurs, methods return <CODECLASS="literal">undef</CODE> in scalar context or an empty list in list context.</P><PCLASS="para">The connection is established with the <CODECLASS="literal">new</CODE> constructor. If an error occurs, <CODECLASS="literal">$@</CODE> is set to an error message and <CODECLASS="literal">new</CODE> returns <CODECLASS="literal">undef</CODE>. The first argument is the hostname of the FTP server and is optionally followed by named options:</P><PRECLASS="programlisting">$ftp = Net::FTP->new("ftp.host.com", Timeout => 30, Debug => 1) or die "Can't connect: $@\n";</PRE><PCLASS="para">The <CODECLASS="literal">Timeout</CODE> option gives the number of seconds all operations wait before giving up. <CODECLASS="literal">Debug</CODE> sets the debugging level (non-zero sends copies of all commands to STDERR). <CODECLASS="literal">Firewall</CODE> takes a string as an argument, specifying the machine acting as an FTP proxy. <CODECLASS="literal">Port</CODE> lets you specify an alternate port number (the default is 21, the standard port for FTP). Finally, if the <CODECLASS="literal">Passive</CODE> option is set to true, all transfers are done passively (some firewalls and proxies require this). The <CODECLASS="literal">Firewall</CODE> and <CODECLASS="literal">Passive</CODE> options override the environment variables <CODECLASS="literal">FTP_FIREWALL</CODE> and <CODECLASS="literal">FTP_PASSIVE</CODE>.</P><PCLASS="para">Having connected, the next step is to authenticate. Normally, you'll want to call <CODECLASS="literal">login</CODE> with up to three arguments: username, password, and account.</P><PRECLASS="programlisting">$ftp-><CODECLASS="literal">login()</CODE> or die "Couldn't authenticate.\n";$ftp->login($username) or die "Still couldn't authenticate.\n";$ftp->login($username, $password) or die "Couldn't authenticate, even with explicit username and password.\n";$ftp->login($username, $password, $account) or die "No dice. It hates me.\n";</PRE><PCLASS="para">If you call <CODECLASS="literal">login</CODE> with no arguments, Net::FTP uses the Net::Netrc module to find settings for the host you've connected to. If none are found there, anonymous login is attempted (username <CODECLASS="literal">anonymous</CODE>, password <CODECLASS="literal">username@hostname</CODE>). If no password is given and the username <CODECLASS="literal">anonymous</CODE> is used, the user's mail address is supplied as the password. The optional account argument is not used on most systems. If the authentication fails, <CODECLASS="literal">login</CODE> returns <CODECLASS="literal">undef</CODE>.</P><PCLASS="para">Once authenticated, the usual FTP commands are available as methods called on your Net::FTP object. The <CODECLASS="literal">get</CODE> and <CODECLASS="literal">put</CODE> methods fetch and send files. To send a file, use:</P><PRECLASS="programlisting">$ftp->put($localfile, $remotefile) or die "Can't send $localfile: $!\n";</PRE><PCLASS="para">If you omit the second argument, the remote file will have the same name as the local file. You can also send from a filehandle (in which case the remote filename must be given as the second argument):</P><PRECLASS="programlisting">$ftp->put(*STDIN, $remotefile) or die "Can't send from STDIN: $!\n";</PRE><PCLASS="para">If the transfer is interrupted, the remote file is not automatically deleted. The <CODECLASS="literal">put</CODE> method returns the remote filename if it succeeded, or <CODECLASS="literal">undef</CODE> if an error occurred.</P><PCLASS="para">To fetch a file, use the <CODECLASS="literal">get</CODE> method, which returns the local filename, or <CODECLASS="literal">undef</CODE> if there was an error:</P><PRECLASS="programlisting">$ftp->get($remotefile, $localfile) or die "Can't fetch $remotefile : $!\n";</PRE><PCLASS="para">You can also <CODECLASS="literal">get</CODE> into a filehandle, in which case the filehandle is returned (or <CODECLASS="literal">undef</CODE> if there was an error):</P><PRECLASS="programlisting">$ftp->get($remotefile, *STDOUT) or die "Can't fetch $remotefile: $!\n";</PRE><PCLASS="para">Pass <CODECLASS="literal">get</CODE> an optional third argument, an offset into the remote file, to begin the transfer at that offset. Received bytes are appended to the local file.</P><PCLASS="para">The <CODECLASS="literal">type</CODE> method changes the file translation mode. Pass it a string (<CODECLASS="literal">"A"</CODE>, <CODECLASS="literal">"I"</CODE>, <CODECLASS="literal">"E"</CODE>, or <CODECLASS="literal">"L"</CODE>) and it will return the previous translation mode. The <CODECLASS="literal">ascii</CODE>, <CODECLASS="literal">binary</CODE>, <CODECLASS="literal">ebcdic</CODE>, and <CODECLASS="literal">byte</CODE> methods call <CODECLASS="literal">type</CODE> with the appropriate string. If an error occurs (the FTP server does not do EBCDIC, for example), <CODECLASS="literal">type</CODE> and its helper methods return <CODECLASS="literal">undef</CODE>.</P><PCLASS="para">Use <CODECLASS="literal">cwd($remotedir)</CODE> and <CODECLASS="literal">pwd</CODE> to set and fetch the current remote directory. They both return true if successful, false otherwise. If you <CODECLASS="literal">cwd("..")</CODE>, the <CODECLASS="literal">cdup</CODE> method is called to change the directory to the parent of the current directory. Call <CODECLASS="literal">cwd</CODE> without an argument to change to the root directory.</P><PRECLASS="programlisting">$ftp->cwd("/pub/perl/CPAN/images/g-rated");print "I'm in the directory ", $ftp->pwd(), "\n";</PRE><PCLASS="para"><CODECLASS="literal">mkdir($remotedir)</CODE> and <CODECLASS="literal">rmdir($remotedir)</CODE> make and delete directories on the remote machine. You have the built-in <CODECLASS="literal">mkdir</CODE> and <CODECLASS="literal">rmdir</CODE> functions to make and delete directories on the local machine. To create all directories up to the given directory, pass a true second argument to <CODECLASS="literal">mkdir</CODE>. For instance, if you want to make <EMCLASS="emphasis">/pub</EM>, <EMCLASS="emphasis">/pub/gnat</EM>, and <EMCLASS="emphasis">/pub/gnat/perl</EM>, say:</P><PRECLASS="programlisting"> $ftp->mkdir("/pub/gnat/perl", 1) or die "Can't create /pub/gnat/perl recursively: $!\n";</PRE><PCLASS="para">If <CODECLASS="literal">mkdir</CODE> succeeds, the full path to the newly created directory is returned. If it fails, <CODECLASS="literal">mkdir</CODE> returns <CODECLASS="literal">undef</CODE>.</P><PCLASS="para">The <CODECLASS="literal">ls</CODE> and <CODECLASS="literal">dir</CODE> methods get a list of files in a remote directory. Traditionally, <CODECLASS="literal">dir</CODE> gives you a more verbose listing than <CODECLASS="literal">ls</CODE>, but neither has a standard format. Most Unix FTP servers return the output of <EMCLASS="emphasis">ls</EM> and <EMCLASS="emphasis">ls -l</EM> respectively, but you can't guarantee that behavior from every FTP server. These methods, in list context, return the list of lines returned by the server. In scalar context, they return a reference to an array.</P><PRECLASS="programlisting">@lines = $ftp->ls("/pub/gnat/perl") or die "Can't get a list of files in /pub/gnat/perl: $!";$ref_to_lines = $ftp->dir("/pub/perl/CPAN/src/latest.tar.gz") or die "Can't check status of latest.tar.gz: $!\n";</PRE><PCLASS="para">When you're done and want to close up gracefully, use the <CODECLASS="literal">quit</CODE> method:</P><PRECLASS="programlisting">$ftp->quit() or warn "Couldn't quit. Oh well.\n";</PRE><PCLASS="para">Other methods rename, change ownership and permissions of remote files, check the size of the remote file, and so on. Read the Net::FTP documentation for details.</P><PCLASS="para">If you want to mirror files between machines, use the excellent <EMCLASS="emphasis">mirror</EM> program written in Perl by Lee McLoughlin. Look for it on the Web at <ACLASS="systemitem.url"HREF="http://sunsite.doc.ic.ac.uk/packages/mirror/.">http://sunsite.doc.ic.ac.uk/packages/mirror/.</A></P></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch18-pgfId-389">See Also</A></H3><PCLASS="para">Your system's <ICLASS="filename">ftp </I>(1) and <ICLASS="filename">ftpd</I> (8) manpages (if you have them); the documentation for the Net::FTP module from CPAN<ACLASS="indexterm"NAME="ch18-idx-1000004289-0"></A><ACLASS="indexterm"NAME="ch18-idx-1000004289-1"></A><ACLASS="indexterm"NAME="ch18-idx-1000004289-2"></A><ACLASS="indexterm"NAME="ch18-idx-1000004289-3"></A></P></DIV></DIV><DIVCLASS="htmlnav"><P></P><HRALIGN="LEFT"WIDTH="684"TITLE="footer"><TABLEWIDTH="684"BORDER="0"CELLSPACING="0"CELLPADDING="0"><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch18_02.htm"TITLE="18.1. Simple DNS Lookups"><IMGSRC="../gifs/txtpreva.gif"ALT="Previous: 18.1. Simple DNS Lookups"BORDER="0"></A></TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="228"><ACLASS="book"HREF="index.htm"TITLE="Perl Cookbook"><IMGSRC="../gifs/txthome.gif"ALT="Perl Cookbook"BORDER="0"></A></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch18_04.htm"TITLE="18.3. Sending Mail"><IMGSRC="../gifs/txtnexta.gif"ALT="Next: 18.3. Sending Mail"BORDER="0"></A></TD></TR><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="228">18.1. Simple DNS Lookups</TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="228"><ACLASS="index"HREF="index/index.htm"TITLE="Book Index"><IMGSRC="../gifs/index.gif"ALT="Book Index"BORDER="0"></A></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="228">18.3. Sending Mail</TD></TR></TABLE><HRALIGN="LEFT"WIDTH="684"TITLE="footer"><FONTSIZE="-1"></DIV<!-- LIBRARY NAV BAR --> <img src="../gifs/smnavbar.gif" usemap="#library-map" border="0" alt="Library Navigation Links"><p> <a href="copyrght.htm">Copyright © 2002</a> O'Reilly & Associates. All rights reserved.</font> </p> <map name="library-map"> <area shape="rect" coords="1,0,85,94" href="../index.htm"><area shape="rect" coords="86,1,178,103" href="../lwp/index.htm"><area shape="rect" coords="180,0,265,103" href="../lperl/index.htm"><area shape="rect" coords="267,0,353,105" href="../perlnut/index.htm"><area shape="rect" coords="354,1,446,115" href="../prog/index.htm"><area shape="rect" coords="448,0,526,132" href="../tk/index.htm"><area shape="rect" coords="528,1,615,119" href="../cookbook/index.htm"><area shape="rect" coords="617,0,690,135" href="../pxml/index.htm"></map> </BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -