⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 perlfaq8.1

📁 视频监控网络部分的协议ddns,的模块的实现代码,请大家大胆指正.
💻 1
📖 第 1 页 / 共 4 页
字号:
.PPTo capture a program's \s-1STDOUT\s0, but discard its \s-1STDERR:\s0.PP.Vb 7\&        use IPC::Open3;\&        use File::Spec;\&        use Symbol qw(gensym);\&        open(NULL, ">", File::Spec\->devnull);\&        my $pid = open3(gensym, \e*PH, ">&NULL", "cmd");\&        while( <PH> ) { }\&        waitpid($pid, 0);.Ve.PPTo capture a program's \s-1STDERR\s0, but discard its \s-1STDOUT:\s0.PP.Vb 7\&        use IPC::Open3;\&        use File::Spec;\&        use Symbol qw(gensym);\&        open(NULL, ">", File::Spec\->devnull);\&        my $pid = open3(gensym, ">&NULL", \e*PH, "cmd");\&        while( <PH> ) { }\&        waitpid($pid, 0);.Ve.PPTo capture a program's \s-1STDERR\s0, and let its \s-1STDOUT\s0 go to our own \s-1STDERR:\s0.PP.Vb 5\&        use IPC::Open3;\&        use Symbol qw(gensym);\&        my $pid = open3(gensym, ">&STDERR", \e*PH, "cmd");\&        while( <PH> ) { }\&        waitpid($pid, 0);.Ve.PPTo read both a command's \s-1STDOUT\s0 and its \s-1STDERR\s0 separately, you canredirect them to temp files, let the command run, then read the tempfiles:.PP.Vb 10\&        use IPC::Open3;\&        use Symbol qw(gensym);\&        use IO::File;\&        local *CATCHOUT = IO::File\->new_tmpfile;\&        local *CATCHERR = IO::File\->new_tmpfile;\&        my $pid = open3(gensym, ">&CATCHOUT", ">&CATCHERR", "cmd");\&        waitpid($pid, 0);\&        seek $_, 0, 0 for \e*CATCHOUT, \e*CATCHERR;\&        while( <CATCHOUT> ) {}\&        while( <CATCHERR> ) {}.Ve.PPBut there's no real need for *both* to be tempfiles... the followingshould work just as well, without deadlocking:.PP.Vb 9\&        use IPC::Open3;\&        use Symbol qw(gensym);\&        use IO::File;\&        local *CATCHERR = IO::File\->new_tmpfile;\&        my $pid = open3(gensym, \e*CATCHOUT, ">&CATCHERR", "cmd");\&        while( <CATCHOUT> ) {}\&        waitpid($pid, 0);\&        seek CATCHERR, 0, 0;\&        while( <CATCHERR> ) {}.Ve.PPAnd it'll be faster, too, since we can begin processing the program'sstdout immediately, rather than waiting for the program to finish..PPWith any of these, you can change file descriptors before the call:.PP.Vb 2\&        open(STDOUT, ">logfile");\&        system("ls");.Ve.PPor you can use Bourne shell file-descriptor redirection:.PP.Vb 2\&        $output = \`$cmd 2>some_file\`;\&        open (PIPE, "cmd 2>some_file |");.Ve.PPYou can also use file-descriptor redirection to make \s-1STDERR\s0 aduplicate of \s-1STDOUT:\s0.PP.Vb 2\&        $output = \`$cmd 2>&1\`;\&        open (PIPE, "cmd 2>&1 |");.Ve.PPNote that you \fIcannot\fR simply open \s-1STDERR\s0 to be a dup of \s-1STDOUT\s0in your Perl program and avoid calling the shell to do the redirection.This doesn't work:.PP.Vb 2\&        open(STDERR, ">&STDOUT");\&        $alloutput = \`cmd args\`;  # stderr still escapes.Ve.PPThis fails because the \fIopen()\fR makes \s-1STDERR\s0 go to where \s-1STDOUT\s0 wasgoing at the time of the \fIopen()\fR.  The backticks then make \s-1STDOUT\s0 go toa string, but don't change \s-1STDERR\s0 (which still goes to the old\&\s-1STDOUT\s0)..PPNote that you \fImust\fR use Bourne shell (\fIsh\fR\|(1)) redirection syntax inbackticks, not \fIcsh\fR\|(1)!  Details on why Perl's \fIsystem()\fR and backtickand pipe opens all use the Bourne shell are in the\&\fIversus/csh.whynot\fR article in the \*(L"Far More Than You Ever Wanted ToKnow\*(R" collection in http://www.cpan.org/misc/olddoc/FMTEYEWTK.tgz .  Tocapture a command's \s-1STDERR\s0 and \s-1STDOUT\s0 together:.PP.Vb 3\&        $output = \`cmd 2>&1\`;                       # either with backticks\&        $pid = open(PH, "cmd 2>&1 |");              # or with an open pipe\&        while (<PH>) { }                            #    plus a read.Ve.PPTo capture a command's \s-1STDOUT\s0 but discard its \s-1STDERR:\s0.PP.Vb 3\&        $output = \`cmd 2>/dev/null\`;                # either with backticks\&        $pid = open(PH, "cmd 2>/dev/null |");       # or with an open pipe\&        while (<PH>) { }                            #    plus a read.Ve.PPTo capture a command's \s-1STDERR\s0 but discard its \s-1STDOUT:\s0.PP.Vb 3\&        $output = \`cmd 2>&1 1>/dev/null\`;           # either with backticks\&        $pid = open(PH, "cmd 2>&1 1>/dev/null |");  # or with an open pipe\&        while (<PH>) { }                            #    plus a read.Ve.PPTo exchange a command's \s-1STDOUT\s0 and \s-1STDERR\s0 in order to capture the \s-1STDERR\s0but leave its \s-1STDOUT\s0 to come out our old \s-1STDERR:\s0.PP.Vb 3\&        $output = \`cmd 3>&1 1>&2 2>&3 3>&\-\`;        # either with backticks\&        $pid = open(PH, "cmd 3>&1 1>&2 2>&3 3>&\-|");# or with an open pipe\&        while (<PH>) { }                            #    plus a read.Ve.PPTo read both a command's \s-1STDOUT\s0 and its \s-1STDERR\s0 separately, it's easiestto redirect them separately to files, and then read from those fileswhen the program is done:.PP.Vb 1\&        system("program args 1>program.stdout 2>program.stderr");.Ve.PPOrdering is important in all these examples.  That's because the shellprocesses file descriptor redirections in strictly left to right order..PP.Vb 2\&        system("prog args 1>tmpfile 2>&1");\&        system("prog args 2>&1 1>tmpfile");.Ve.PPThe first command sends both standard out and standard error to thetemporary file.  The second command sends only the old standard outputthere, and the old standard error shows up on the old standard out..Sh "Why doesn't \fIopen()\fP return an error when a pipe open fails?".IX Subsection "Why doesn't open() return an error when a pipe open fails?"If the second argument to a piped \fIopen()\fR contains shellmetacharacters, perl \fIfork()\fRs, then \fIexec()\fRs a shell to decode themetacharacters and eventually run the desired program.  If the programcouldn't be run, it's the shell that gets the message, not Perl. Allyour Perl program can find out is whether the shell itself could besuccessfully started.  You can still capture the shell's \s-1STDERR\s0 andcheck it for error messages.  See \*(L"How can I capture \s-1STDERR\s0 from anexternal command?\*(R" elsewhere in this document, or use theIPC::Open3 module..PPIf there are no shell metacharacters in the argument of \fIopen()\fR, Perlruns the command directly, without using the shell, and can correctlyreport whether the command started..Sh "What's wrong with using backticks in a void context?".IX Subsection "What's wrong with using backticks in a void context?"Strictly speaking, nothing.  Stylistically speaking, it's not a goodway to write maintainable code.  Perl has several operators forrunning external commands.  Backticks are one; they collect the outputfrom the command for use in your program.  The \f(CW\*(C`system\*(C'\fR function isanother; it doesn't do this..PPWriting backticks in your program sends a clear message to the readersof your code that you wanted to collect the output of the command.Why send a clear message that isn't true?.PPConsider this line:.PP.Vb 1\&        \`cat /etc/termcap\`;.Ve.PPYou forgot to check \f(CW$?\fR to see whether the program even rancorrectly.  Even if you wrote.PP.Vb 1\&        print \`cat /etc/termcap\`;.Ve.PPthis code could and probably should be written as.PP.Vb 2\&        system("cat /etc/termcap") == 0\&        or die "cat program failed!";.Ve.PPwhich will echo the cat command's output as it is generated, insteadof waiting until the program has completed to print it out. It alsochecks the return value..PP\&\f(CW\*(C`system\*(C'\fR also provides direct control over whether shell wildcardprocessing may take place, whereas backticks do not..Sh "How can I call backticks without shell processing?".IX Subsection "How can I call backticks without shell processing?"This is a bit tricky.  You can't simply write the commandlike this:.PP.Vb 1\&        @ok = \`grep @opts \*(Aq$search_string\*(Aq @filenames\`;.Ve.PPAs of Perl 5.8.0, you can use \f(CW\*(C`open()\*(C'\fR with multiple arguments.Just like the list forms of \f(CW\*(C`system()\*(C'\fR and \f(CW\*(C`exec()\*(C'\fR, no shellescapes happen..PP.Vb 3\&        open( GREP, "\-|", \*(Aqgrep\*(Aq, @opts, $search_string, @filenames );\&        chomp(@ok = <GREP>);\&        close GREP;.Ve.PPYou can also:.PP.Vb 10\&        my @ok = ();\&        if (open(GREP, "\-|")) {\&                while (<GREP>) {\&                        chomp;\&                        push(@ok, $_);\&                }\&                close GREP;\&        } else {\&                exec \*(Aqgrep\*(Aq, @opts, $search_string, @filenames;\&        }.Ve.PPJust as with \f(CW\*(C`system()\*(C'\fR, no shell escapes happen when you \f(CW\*(C`exec()\*(C'\fR alist. Further examples of this can be found in \*(L"Safe PipeOpens\*(R" in perlipc..PPNote that if you're using Windows, no solution to this vexing issue iseven possible.  Even if Perl were to emulate \f(CW\*(C`fork()\*(C'\fR, you'd still bestuck, because Windows does not have an argc/argv\-style \s-1API\s0..Sh "Why can't my script read from \s-1STDIN\s0 after I gave it \s-1EOF\s0 (^D on Unix, ^Z on MS-DOS)?".IX Subsection "Why can't my script read from STDIN after I gave it EOF (^D on Unix, ^Z on MS-DOS)?"Some stdio's set error and eof flags that need clearing.  The\&\s-1POSIX\s0 module defines \fIclearerr()\fR that you can use.  That is thetechnically correct way to do it.  Here are some less reliableworkarounds:.IP "1." 4Try keeping around the seekpointer and go there, like this:.Sp.Vb 2\&        $where = tell(LOG);\&        seek(LOG, $where, 0);.Ve.IP "2." 4If that doesn't work, try seeking to a different part of the file andthen back..IP "3." 4If that doesn't work, try seeking to a different part ofthe file, reading something, and then seeking back..IP "4." 4If that doesn't work, give up on your stdio package and use sysread..Sh "How can I convert my shell script to perl?".IX Subsection "How can I convert my shell script to perl?"Learn Perl and rewrite it.  Seriously, there's no simple converter.Things that are awkward to do in the shell are easy to do in Perl, andthis very awkwardness is what would make a shell\->perl converternigh-on impossible to write.  By rewriting it, you'll think about whatyou're really trying to do, and hopefully will escape the shell'spipeline datastream paradigm, which while convenient for some matters,causes many inefficiencies..Sh "Can I use perl to run a telnet or ftp session?".IX Subsection "Can I use perl to run a telnet or ftp session?"Try the Net::FTP, TCP::Client, and Net::Telnet modules (available from\&\s-1CPAN\s0).  http://www.cpan.org/scripts/netstuff/telnet.emul.sharwill also help for emulating the telnet protocol, but Net::Telnet isquite probably easier to use...PPIf all you want to do is pretend to be telnet but don't needthe initial telnet handshaking, then the standard dual-processapproach will suffice:.PP.Vb 12\&        use IO::Socket;             # new in 5.004\&        $handle = IO::Socket::INET\->new(\*(Aqwww.perl.com:80\*(Aq)\&            or die "can\*(Aqt connect to port 80 on www.perl.com: $!";\&        $handle\->autoflush(1);\&        if (fork()) {               # XXX: undef means failure\&            select($handle);\&            print while <STDIN>;    # everything from stdin to socket\&        } else {\&            print while <$handle>;  # everything from socket to stdout\&        }\&        close $handle;\&        exit;.Ve.Sh "How can I write expect in Perl?".IX Subsection "How can I write expect in Perl?"Once upon a time, there was a library called chat2.pl (part of thestandard perl distribution), which never really got finished.  If youfind it somewhere, \fIdon't use it\fR.  These days, your best bet is tolook at the Expect module available from \s-1CPAN\s0, which also requires twoother modules from \s-1CPAN\s0, IO::Pty and IO::Stty..ie n .Sh "Is there a way to hide perl's command line from programs such as ""ps""?".el .Sh "Is there a way to hide perl's command line from programs such as ``ps''?".IX Subsection "Is there a way to hide perl's command line from programs such as ps?"First of all note that if you're doing this for security reasons (toavoid people seeing passwords, for example) then you should rewriteyour program so that critical information is never given as anargument.  Hiding the arguments won't make your program completelysecure..PPTo actually alter the visible command line, you can assign to thevariable \f(CW$0\fR as documented in perlvar.  This won't work on alloperating systems, though.  Daemon programs like sendmail place theirstate there, as in:.PP.Vb 1\&        $0 = "orcus [accepting connections]";.Ve.Sh "I {changed directory, modified my environment} in a perl script.  How come the change disappeared when I exited the script?  How do I get my changes to be visible?".IX Subsection "I {changed directory, modified my environment} in a perl script.  How come the change disappeared when I exited the script?  How do I get my changes to be visible?".IP "Unix" 4.IX Item "Unix"In the strictest sense, it can't be done\*(--the script executes as adifferent process from the shell it was started from.  Changes to aprocess are not reflected in its parent\*(--only in any childrencreated after the change.  There is shell magic that may allow you tofake it by \fIeval()\fRing the script's output in your shell; check out thecomp.unix.questions \s-1FAQ\s0 for details..Sh "How do I close a process's filehandle without waiting for it to complete?".IX Subsection "How do I close a process's filehandle without waiting for it to complete?"Assuming your system supports such things, just send an appropriate signalto the process (see \*(L"kill\*(R" in perlfunc).  It's common to first send a \s-1TERM\s0signal, wait a little bit, and then send a \s-1KILL\s0 signal to finish it off..Sh "How do I fork a daemon process?".IX Subsection "How do I fork a daemon process?"If by daemon process you mean one that's detached (disassociated fromits tty), then the following process is reported to work on mostUnixish systems.  Non-Unix users should check their Your_OS::Processmodule for other solutions..IP "\(bu" 4Open /dev/tty and use the \s-1TIOCNOTTY\s0 ioctl on it.  See ttyfor details.  Or better yet, you can just use the \fIPOSIX::setsid()\fRfunction, so you don't have to worry about process groups..IP "\(bu" 4Change directory to /.IP "\(bu" 4Reopen \s-1STDIN\s0, \s-1STDOUT\s0, and \s-1STDERR\s0 so they're not connected to the oldtty..IP "\(bu" 4Background yourself like this:.Sp.Vb 1\&        fork && exit;.Ve.PPThe Proc::Daemon module, available from \s-1CPAN\s0, provides a function toperform these actions for you..Sh "How do I find out if I'm running interactively or not?".IX Subsection "How do I find out if I'm running interactively or not?"Good question. Sometimes \f(CW\*(C`\-t STDIN\*(C'\fR and \f(CW\*(C`\-t STDOUT\*(C'\fR can give clues,sometimes not.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -