📄 2.b.rlogin
字号:
#!/usr/local/bin/perl# There are three new things in this example. First is the concept#of closing the process, second is the concept of using regular#expressions in match patterns, and third is the concept of grabbing#stuff that is in the process's buffer. This last part is like when you#telnet to a host, do ls, and want to know the name of the files returned:###somehost$ ls#thing#thing.gz#core#Mail#mail#somehost$ ## When you use the expect() function it is possible to grab the#data before the next patter looked for. in this case if you were#looking for "somehost$ " you could get the names of the files returned#in the ls. In the example below the output of the 'id' command is grabbed#for use by the program.## What this example tries to do is log in to foreign hosts and#grab the user id on each host.#use Expect;# Optional debugging, explained later.# $Expect::Debug=1# $Expect::Exp_Internal=1;# $Expect::Log_Stdout=0; # On by default.die "Usage: $0 host1 host2... hostn\n" unless defined $ARGV[0];@hosts = @ARGV;# Ssh would be better, rlogin is used here because it is more familiar.foreach $host (@hosts) { $rlogin=Expect->spawn("rlogin $host"); $rlogin->expect(30,"ssword: ") || die "Never got password prompt on $host, ".$rlogin->exp_error()."\n";# We got the prompt, so send a password. print $rlogin "H4yB3vis\r";# Now we look for a shell prompt. Notice the use of the regular expression.# To use a regexp make the previous argument '-re'.# expect will match on the hostname followed by a %, >, or $ followed by# whitespace. Notice that the regular expression part is in single quotes.# This is so that perl won't interpret control characters such as # whitespace (\s) for us until it gets in to the pattern matching engine.# my prompt is "darkwing$ ". Yours is probably different.# The below expect() call will return 1 if it matches the closed by foreign# host string or 2 if it matches the regular expression.# undef is returned if nothing matches. $match=$rlogin->expect(30,"closed by foreign host","-re",$host.'[%>$]\s'); die "Dumped by server\n" if $match == 1; die "Never got shell prompt on $host, ".$rlogin->exp_error()."\n" unless $match;# Ok, so we have a shell prompt. let's give it the 'id' command. print $rlogin "id\r";# Now, we know that because ther terminal will echo "id\r" back to us# we should grab it so it won't muck with our final output.# Also, on most terminals if you send a carriage return it will respond# with a carriage return-newline combination. So we do: $rlogin->expect(30,"id\r\n");# which clears id out of the buffer. Note that I used \r\n in double# quotes instead of single quotes because I want perl to look for# a carriage return instead of the literal \r\n. If I had instead done# $rlogin->expect(30,'-re','id\r\n'); it would work because it gets# tossed in to a regular expression where \r and \n get evaluated.# Now when we use expect() to find the next prompt the output of the last# command will be in the buffer that holds output between expect() calls.# this output should be 'before' we match.# I'm going to define what prompt we're looking for ahead of time to# make the call to expect more readable. $prompt = $host.'[%>$]\s'; $rlogin->expect(30,'-re',$prompt);# Yet another way to find out if we had a successful match is to test for# an error. die "Never got prompt after sending 'id' command\n" if $rlogin->exp_error();# And the output of id: print "id on $host: $rlogin->exp_before()";# Now, we do a hard close here. We are positively done with rlogin and we# know that it won't be ending by itself. This would be unlike, say, # a command like "tail /etc/passwd" which will exit as soon as it is finished# sending us its output. For that sort of a command soft_close() would # suffice.# It is important that you close rlogin so that processes don't # pile up eating your system resources during further loops through# hosts. $rlogin->hard_close();# next host}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -