📄 ch15_14.htm
字号:
<HTML><HEAD><TITLE>Recipe 15.13. Controlling Another Program with Expect (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:43:26Z"><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="ch15_01.htm"TITLE="15. User Interfaces"><LINKREL="prev"HREF="ch15_13.htm"TITLE="15.12. Managing the Screen"><LINKREL="next"HREF="ch15_15.htm"TITLE="15.14. Creating Menus with Tk"></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="ch15_13.htm"TITLE="15.12. Managing the Screen"><IMGSRC="../gifs/txtpreva.gif"ALT="Previous: 15.12. Managing the Screen"BORDER="0"></A></TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="228"><B><FONTFACE="ARIEL,HELVETICA,HELV,SANSERIF"SIZE="-1"><ACLASS="chapter"REL="up"HREF="ch15_01.htm"TITLE="15. User Interfaces"></A></FONT></B></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch15_15.htm"TITLE="15.14. Creating Menus with Tk"><IMGSRC="../gifs/txtnexta.gif"ALT="Next: 15.14. Creating Menus with Tk"BORDER="0"></A></TD></TR></TABLE></DIV><DIVCLASS="sect1"><H2CLASS="sect1"><ACLASS="title"NAME="ch15-28528">15.13. Controlling Another Program with Expect</A></H2><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch15-pgfId-1281">Problem<ACLASS="indexterm"NAME="ch15-idx-1000005146-0"></A><ACLASS="indexterm"NAME="ch15-idx-1000005146-1"></A><ACLASS="indexterm"NAME="ch15-idx-1000005146-2"></A><ACLASS="indexterm"NAME="ch15-idx-1000005146-3"></A></A></H3><PCLASS="para">You want to automate interaction with a full-screen program that expects to have a terminal behind STDIN and STDOUT.</P></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch15-pgfId-1287">Solution</A></H3><PCLASS="para">Use the Expect module from CPAN:</P><PRECLASS="programlisting">use Expect;$command = Expect->spawn("program to run") or die "Couldn't start program: $!\n";# prevent the program's output from being shown on our STDOUT$command->log_stdout(0);# wait 10 seconds for "Password:" to appearunless ($command->expect(10, "Password")) { # timed out}# wait 20 seconds for something that matches /[lL]ogin: ?/unless ($command->expect(20, -re => '[lL]ogin: ?')) { # timed out}# wait forever for "invalid" to appearunless ($command->expect(undef, "invalid")) { # error occurred; the program probably went away}# send "Hello, world" and a carriage return to the programprint $command "Hello, world\r";# if the program will terminate by itself, finish up with$command->soft_close(); # if the program must be explicitly killed, finish up with$command->hard_close();</PRE></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch15-pgfId-1355">Discussion</A></H3><PCLASS="para">This module requires two other modules from CPAN: <ACLASS="indexterm"NAME="ch15-idx-1000005152-0"></A><ACLASS="indexterm"NAME="ch15-idx-1000005152-1"></A>IO::Pty and IO::Stty. It sets up a pseudo-terminal to interact with programs that insist on using talking to the terminal device driver. People often use this for talking to <EMCLASS="emphasis">passwd</EM> to change passwords. <EMCLASS="emphasis">telnet</EM> (Net::Telnet, described in <ACLASS="xref"HREF="ch18_07.htm"TITLE="Simulating Telnet from a Program">Recipe 18.6</A>, is probably more suitable and portable) and <EMCLASS="emphasis">ftp</EM> are also programs that expect a real tty.</P><PCLASS="para">Start the program you want to run with <CODECLASS="literal">Expect->spawn</CODE>, passing a program name and arguments either in a single string or as a list. Expect starts the program and returns an object representing that program, or <CODECLASS="literal">undef</CODE> if the program couldn't be started.</P><PCLASS="para">To wait for the program to emit a particular string, use the <CODECLASS="literal">expect</CODE> method. Its first argument is the number of seconds to wait for the string, or <CODECLASS="literal">undef</CODE> to wait forever. To wait for a string, give that string as the second argument to <CODECLASS="literal">expect</CODE>. To wait for a regular expression, give <CODECLASS="literal">"-re"</CODE> as the second argument and a string containing the pattern as the third argument. You can give further strings or patterns to wait for:</P><PRECLASS="programlisting">$which = $command->expect(30, "invalid", "succes", "error", "boom");if ($which) { # found one of those strings}</PRE><PCLASS="para">In scalar context, <CODECLASS="literal">expect</CODE> returns the number of arguments it matched. In the example above, <CODECLASS="literal">expect</CODE> would return 1 if the program emitted <CODECLASS="literal">"invalid"</CODE>, 2 if it emitted <CODECLASS="literal">"succes"</CODE>, and so on. If none of the patterns or strings matches, <CODECLASS="literal">expect</CODE> returns false.</P><PCLASS="para">In list context, <CODECLASS="literal">expect</CODE> returns a five-element list. The first element is the number of the pattern or string that matched, the same as its return value in scalar context. The second argument is a string indicating why <CODECLASS="literal">expect</CODE> returned. If there were no error, the second argument will be <CODECLASS="literal">undef</CODE>. Possible errors are <CODECLASS="literal">"1:TIMEOUT"</CODE>, <CODECLASS="literal">"2:EOF"</CODE>, <CODECLASS="literal">"3:spawn</CODE> <CODECLASS="literal">id(...)died"</CODE> and <CODECLASS="literal">"4:..."</CODE>. (See the <ICLASS="filename">Expect </I>(3) manpage for the precise meaning of these messages.) The third argument of <CODECLASS="literal">expect</CODE>'s return list is the string matched. The fourth argument is text before the match, and the fifth argument is text after the match.</P><PCLASS="para">Sending <ACLASS="indexterm"NAME="ch15-idx-1000005153-0"></A>input to the program you're controlling with Expect is as simple as using <CODECLASS="literal">print</CODE>. The only catch is that terminals, devices, and sockets all vary in what they send and expect as the line terminator - we've left the sanctuary of the C standard I/O library, so the behind-the-scenes conversion to <CODECLASS="literal">"\n"</CODE> isn't taking place. We recommend trying <CODECLASS="literal">"\r"</CODE> at first. If that doesn't work, try <CODECLASS="literal">"\n"</CODE> and <CODECLASS="literal">"\r\n"</CODE>.</P><PCLASS="para">When you're finished with the spawned program, you have three options. One, you can continue with your main program, and the spawned program will be forcibly killed when the main program ends. This will accumulate processes, though. Two, if you know the spawned program will terminate normally either when it has finished sending you output or because you told it to stop - for example, <EMCLASS="emphasis">telnet</EM> after you exit the remote shell - call the <CODECLASS="literal">soft_close</CODE> method. If the spawned program could continue forever, like <EMCLASS="emphasis">tail -f</EM>, then use the <CODECLASS="literal">hard_close</CODE> method; this kills the spawned program.<ACLASS="indexterm"NAME="ch15-idx-1000005148-0"></A><ACLASS="indexterm"NAME="ch15-idx-1000005148-1"></A><ACLASS="indexterm"NAME="ch15-idx-1000005148-2"></A><ACLASS="indexterm"NAME="ch15-idx-1000005148-3"></A><ACLASS="indexterm"NAME="ch15-idx-1000005148-4"></A></P></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch15-pgfId-1381">See Also</A></H3><PCLASS="para">The documentation for the Expect, IO::Pty, and IO::Stty modules from CPAN; <CITECLASS="citetitle">Exploring Expect</CITE>, by Don Libes, O'Reilly & Associates (1995).</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="ch15_13.htm"TITLE="15.12. Managing the Screen"><IMGSRC="../gifs/txtpreva.gif"ALT="Previous: 15.12. Managing the Screen"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="ch15_15.htm"TITLE="15.14. Creating Menus with Tk"><IMGSRC="../gifs/txtnexta.gif"ALT="Next: 15.14. Creating Menus with Tk"BORDER="0"></A></TD></TR><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="228">15.12. Managing the Screen</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">15.14. Creating Menus with Tk</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 + -