Filename | /2home/ss5/perl5/perlbrew/perls/perl-5.12.3/lib/site_perl/5.12.3/Net/SSH.pm |
Statements | Executed 30 statements in 1.12ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
1 | 1 | 1 | 1.53ms | 1.77ms | BEGIN@9 | Net::SSH::
1 | 1 | 1 | 949µs | 1.11ms | BEGIN@8 | Net::SSH::
1 | 1 | 1 | 601µs | 4.84ms | BEGIN@7 | Net::SSH::
1 | 1 | 1 | 16µs | 20µs | BEGIN@3 | Net::SSH::
1 | 1 | 1 | 9µs | 179µs | BEGIN@6 | Net::SSH::
1 | 1 | 1 | 9µs | 26µs | BEGIN@10 | Net::SSH::
1 | 1 | 1 | 9µs | 95µs | BEGIN@4 | Net::SSH::
1 | 1 | 1 | 9µs | 22µs | BEGIN@5 | Net::SSH::
0 | 0 | 0 | 0s | 0s | _ssh_options | Net::SSH::
0 | 0 | 0 | 0s | 0s | _yesno | Net::SSH::
0 | 0 | 0 | 0s | 0s | issh | Net::SSH::
0 | 0 | 0 | 0s | 0s | ssh | Net::SSH::
0 | 0 | 0 | 0s | 0s | ssh_cmd | Net::SSH::
0 | 0 | 0 | 0s | 0s | sshopen2 | Net::SSH::
0 | 0 | 0 | 0s | 0s | sshopen3 | Net::SSH::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | package Net::SSH; | ||||
2 | |||||
3 | 3 | 27µs | 2 | 25µs | # spent 20µs (16+5) within Net::SSH::BEGIN@3 which was called:
# once (16µs+5µs) by Tapper::MCP::Net::BEGIN@11 at line 3 # spent 20µs making 1 call to Net::SSH::BEGIN@3
# spent 5µs making 1 call to strict::import |
4 | 3 | 22µs | 2 | 181µs | # spent 95µs (9+86) within Net::SSH::BEGIN@4 which was called:
# once (9µs+86µs) by Tapper::MCP::Net::BEGIN@11 at line 4 # spent 95µs making 1 call to Net::SSH::BEGIN@4
# spent 86µs making 1 call to vars::import |
5 | 3 | 20µs | 2 | 36µs | # spent 22µs (9+14) within Net::SSH::BEGIN@5 which was called:
# once (9µs+14µs) by Tapper::MCP::Net::BEGIN@11 at line 5 # spent 22µs making 1 call to Net::SSH::BEGIN@5
# spent 14µs making 1 call to Exporter::import |
6 | 3 | 22µs | 2 | 348µs | # spent 179µs (9+170) within Net::SSH::BEGIN@6 which was called:
# once (9µs+170µs) by Tapper::MCP::Net::BEGIN@11 at line 6 # spent 179µs making 1 call to Net::SSH::BEGIN@6
# spent 170µs making 1 call to POSIX::import |
7 | 3 | 129µs | 2 | 4.97ms | # spent 4.84ms (601µs+4.24) within Net::SSH::BEGIN@7 which was called:
# once (601µs+4.24ms) by Tapper::MCP::Net::BEGIN@11 at line 7 # spent 4.84ms making 1 call to Net::SSH::BEGIN@7
# spent 129µs making 1 call to Exporter::import |
8 | 3 | 112µs | 2 | 1.14ms | # spent 1.11ms (949µs+165µs) within Net::SSH::BEGIN@8 which was called:
# once (949µs+165µs) by Tapper::MCP::Net::BEGIN@11 at line 8 # spent 1.11ms making 1 call to Net::SSH::BEGIN@8
# spent 24µs making 1 call to Exporter::import |
9 | 3 | 99µs | 2 | 1.80ms | # spent 1.77ms (1.53+236µs) within Net::SSH::BEGIN@9 which was called:
# once (1.53ms+236µs) by Tapper::MCP::Net::BEGIN@11 at line 9 # spent 1.77ms making 1 call to Net::SSH::BEGIN@9
# spent 25µs making 1 call to Exporter::import |
10 | 3 | 680µs | 2 | 43µs | # spent 26µs (9+17) within Net::SSH::BEGIN@10 which was called:
# once (9µs+17µs) by Tapper::MCP::Net::BEGIN@11 at line 10 # spent 26µs making 1 call to Net::SSH::BEGIN@10
# spent 17µs making 1 call to Exporter::import |
11 | |||||
12 | 1 | 7µs | @ISA = qw(Exporter); | ||
13 | 1 | 1µs | @EXPORT_OK = qw( ssh issh ssh_cmd sshopen2 sshopen3 ); | ||
14 | 1 | 400ns | $VERSION = '0.09'; | ||
15 | |||||
16 | 1 | 300ns | $DEBUG = 0; | ||
17 | |||||
18 | 1 | 300ns | $ssh = "ssh"; | ||
19 | |||||
20 | =head1 NAME | ||||
21 | |||||
22 | Net::SSH - Perl extension for secure shell | ||||
23 | |||||
24 | =head1 SYNOPSIS | ||||
25 | |||||
26 | use Net::SSH qw(ssh issh sshopen2 sshopen3); | ||||
27 | |||||
28 | ssh('user@hostname', $command); | ||||
29 | |||||
30 | issh('user@hostname', $command); | ||||
31 | |||||
32 | ssh_cmd('user@hostname', $command); | ||||
33 | ssh_cmd( { | ||||
34 | user => 'user', | ||||
35 | host => 'host.name', | ||||
36 | command => 'command', | ||||
37 | args => [ '-arg1', '-arg2' ], | ||||
38 | stdin_string => "string\n", | ||||
39 | } ); | ||||
40 | |||||
41 | sshopen2('user@hostname', $reader, $writer, $command); | ||||
42 | |||||
43 | sshopen3('user@hostname', $writer, $reader, $error, $command); | ||||
44 | |||||
45 | =head1 DESCRIPTION | ||||
46 | |||||
47 | Simple wrappers around ssh commands. | ||||
48 | |||||
49 | For an all-perl implementation that does not require the system B<ssh> command, | ||||
50 | see L<Net::SSH::Perl> instead. | ||||
51 | |||||
52 | =head1 SUBROUTINES | ||||
53 | |||||
54 | =over 4 | ||||
55 | |||||
56 | =item ssh [USER@]HOST, COMMAND [, ARGS ... ] | ||||
57 | |||||
58 | Calls ssh in batch mode. | ||||
59 | |||||
60 | =cut | ||||
61 | |||||
62 | sub ssh { | ||||
63 | my($host, @command) = @_; | ||||
64 | @ssh_options = &_ssh_options unless @ssh_options; | ||||
65 | my @cmd = ($ssh, @ssh_options, $host, @command); | ||||
66 | warn "[Net::SSH::ssh] executing ". join(' ', @cmd). "\n" | ||||
67 | if $DEBUG; | ||||
68 | system(@cmd); | ||||
69 | } | ||||
70 | |||||
71 | =item issh [USER@]HOST, COMMAND [, ARGS ... ] | ||||
72 | |||||
73 | Prints the ssh command to be executed, waits for the user to confirm, and | ||||
74 | (optionally) executes the command. | ||||
75 | |||||
76 | =cut | ||||
77 | |||||
78 | sub issh { | ||||
79 | my($host, @command) = @_; | ||||
80 | my @cmd = ($ssh, $host, @command); | ||||
81 | print join(' ', @cmd), "\n"; | ||||
82 | if ( &_yesno ) { | ||||
83 | system(@cmd); | ||||
84 | } | ||||
85 | } | ||||
86 | |||||
87 | =item ssh_cmd [USER@]HOST, COMMAND [, ARGS ... ] | ||||
88 | |||||
89 | =item ssh_cmd OPTIONS_HASHREF | ||||
90 | |||||
91 | Calls ssh in batch mode. Throws a fatal error if data occurs on the command's | ||||
92 | STDERR. Returns any data from the command's STDOUT. | ||||
93 | |||||
94 | If using the hashref-style of passing arguments, possible keys are: | ||||
95 | |||||
96 | user (optional) | ||||
97 | host (requried) | ||||
98 | command (required) | ||||
99 | args (optional, arrayref) | ||||
100 | stdin_string (optional) - written to the command's STDIN | ||||
101 | |||||
102 | =cut | ||||
103 | |||||
104 | sub ssh_cmd { | ||||
105 | my($host, $stdin_string, @command); | ||||
106 | if ( ref($_[0]) ) { | ||||
107 | my $opt = shift; | ||||
108 | $host = $opt->{host}; | ||||
109 | $host = $opt->{user}. '@'. $host if exists $opt->{user}; | ||||
110 | @command = ( $opt->{command} ); | ||||
111 | push @command, @{ $opt->{args} } if exists $opt->{args}; | ||||
112 | $stdin_string = $opt->{stdin_string}; | ||||
113 | } else { | ||||
114 | ($host, @command) = @_; | ||||
115 | undef $stdin_string; | ||||
116 | } | ||||
117 | |||||
118 | my $reader = IO::File->new(); | ||||
119 | my $writer = IO::File->new(); | ||||
120 | my $error = IO::File->new(); | ||||
121 | |||||
122 | my $pid = sshopen3( $host, $writer, $reader, $error, @command ) or die $!; | ||||
123 | |||||
124 | print $writer $stdin_string if defined $stdin_string; | ||||
125 | close $writer; | ||||
126 | |||||
127 | my $select = new IO::Select; | ||||
128 | foreach ( $reader, $error ) { $select->add($_); } | ||||
129 | |||||
130 | my($output_stream, $error_stream) = ('', ''); | ||||
131 | while ( $select->count ) { | ||||
132 | my @handles = $select->can_read; | ||||
133 | foreach my $handle ( @handles ) { | ||||
134 | my $buffer = ''; | ||||
135 | my $bytes = sysread($handle, $buffer, 4096); | ||||
136 | if ( !defined($bytes) ) { | ||||
137 | waitpid($pid, WNOHANG); | ||||
138 | die "[Net::SSH::ssh_cmd] $!" | ||||
139 | }; | ||||
140 | $select->remove($handle) if !$bytes; | ||||
141 | if ( $handle eq $reader ) { | ||||
142 | $output_stream .= $buffer; | ||||
143 | } elsif ( $handle eq $error ) { | ||||
144 | $error_stream .= $buffer; | ||||
145 | } | ||||
146 | } | ||||
147 | |||||
148 | } | ||||
149 | |||||
150 | waitpid($pid, WNOHANG); | ||||
151 | |||||
152 | die "$error_stream" if length($error_stream); | ||||
153 | |||||
154 | return $output_stream; | ||||
155 | |||||
156 | } | ||||
157 | |||||
158 | =item sshopen2 [USER@]HOST, READER, WRITER, COMMAND [, ARGS ... ] | ||||
159 | |||||
160 | Connects the supplied filehandles to the ssh process (in batch mode). | ||||
161 | |||||
162 | =cut | ||||
163 | |||||
164 | sub sshopen2 { | ||||
165 | my($host, $reader, $writer, @command) = @_; | ||||
166 | @ssh_options = &_ssh_options unless @ssh_options; | ||||
167 | open2($reader, $writer, $ssh, @ssh_options, $host, @command); | ||||
168 | } | ||||
169 | |||||
170 | =item sshopen3 HOST, WRITER, READER, ERROR, COMMAND [, ARGS ... ] | ||||
171 | |||||
172 | Connects the supplied filehandles to the ssh process (in batch mode). | ||||
173 | |||||
174 | =cut | ||||
175 | |||||
176 | sub sshopen3 { | ||||
177 | my($host, $writer, $reader, $error, @command) = @_; | ||||
178 | @ssh_options = &_ssh_options unless @ssh_options; | ||||
179 | open3($writer, $reader, $error, $ssh, @ssh_options, $host, @command); | ||||
180 | } | ||||
181 | |||||
182 | sub _yesno { | ||||
183 | print "Proceed [y/N]:"; | ||||
184 | my $x = scalar(<STDIN>); | ||||
185 | $x =~ /^y/i; | ||||
186 | } | ||||
187 | |||||
188 | sub _ssh_options { | ||||
189 | my $reader = IO::File->new(); | ||||
190 | my $writer = IO::File->new(); | ||||
191 | my $error = IO::File->new(); | ||||
192 | open3($writer, $reader, $error, $ssh, '-V'); | ||||
193 | my $ssh_version = <$error>; | ||||
194 | chomp($ssh_version); | ||||
195 | if ( $ssh_version =~ /.*OpenSSH[-|_](\w+)\./ && $1 == 1 ) { | ||||
196 | $equalspace = " "; | ||||
197 | } else { | ||||
198 | $equalspace = "="; | ||||
199 | } | ||||
200 | my @options = ( '-o', 'BatchMode'.$equalspace.'yes' ); | ||||
201 | if ( $ssh_version =~ /.*OpenSSH[-|_](\w+)\./ && $1 > 1 ) { | ||||
202 | unshift @options, '-T'; | ||||
203 | } | ||||
204 | @options; | ||||
205 | } | ||||
206 | |||||
207 | =back | ||||
208 | |||||
209 | =head1 EXAMPLE | ||||
210 | |||||
211 | use Net::SSH qw(sshopen2); | ||||
212 | use strict; | ||||
213 | |||||
214 | my $user = "username"; | ||||
215 | my $host = "hostname"; | ||||
216 | my $cmd = "command"; | ||||
217 | |||||
218 | sshopen2("$user\@$host", *READER, *WRITER, "$cmd") || die "ssh: $!"; | ||||
219 | |||||
220 | while (<READER>) { | ||||
221 | chomp(); | ||||
222 | print "$_\n"; | ||||
223 | } | ||||
224 | |||||
225 | close(READER); | ||||
226 | close(WRITER); | ||||
227 | |||||
228 | =head1 FREQUENTLY ASKED QUESTIONS | ||||
229 | |||||
230 | Q: How do you supply a password to connect with ssh within a perl script | ||||
231 | using the Net::SSH module? | ||||
232 | |||||
233 | A: You don't (at least not with this module). Use RSA or DSA keys. See the | ||||
234 | quick help in the next section and the ssh-keygen(1) manpage. | ||||
235 | |||||
236 | A #2: See L<Net::SSH::Expect> instead. | ||||
237 | |||||
238 | Q: My script is "leaking" ssh processes. | ||||
239 | |||||
240 | A: See L<perlfaq8/"How do I avoid zombies on a Unix system">, L<IPC::Open2>, | ||||
241 | L<IPC::Open3> and L<perlfunc/waitpid>. | ||||
242 | |||||
243 | =head1 GENERATING AND USING SSH KEYS | ||||
244 | |||||
245 | =over 4 | ||||
246 | |||||
247 | =item 1 Generate keys | ||||
248 | |||||
249 | Type: | ||||
250 | |||||
251 | ssh-keygen -t rsa | ||||
252 | |||||
253 | And do not enter a passphrase unless you wanted to be prompted for | ||||
254 | one during file copying. | ||||
255 | |||||
256 | Here is what you will see: | ||||
257 | |||||
258 | $ ssh-keygen -t rsa | ||||
259 | Generating public/private rsa key pair. | ||||
260 | Enter file in which to save the key (/home/User/.ssh/id_rsa): | ||||
261 | Enter passphrase (empty for no passphrase): | ||||
262 | |||||
263 | Enter same passphrase again: | ||||
264 | |||||
265 | Your identification has been saved in /home/User/.ssh/id_rsa. | ||||
266 | Your public key has been saved in /home/User/.ssh/id_rsa.pub. | ||||
267 | The key fingerprint is: | ||||
268 | 5a:cd:2b:0a:cd:d9:15:85:26:79:40:0c:55:2a:f4:23 User@JEFF-CPU | ||||
269 | |||||
270 | |||||
271 | =item 2 Copy public to machines you want to upload to | ||||
272 | |||||
273 | C<id_rsa.pub> is your public key. Copy it to C<~/.ssh> on target machine. | ||||
274 | |||||
275 | Put a copy of the public key file on each machine you want to log into. | ||||
276 | Name the copy C<authorized_keys> (some implementations name this file | ||||
277 | C<authorized_keys2>) | ||||
278 | |||||
279 | Then type: | ||||
280 | |||||
281 | chmod 600 authorized_keys | ||||
282 | |||||
283 | Then make sure your home dir on the remote machine is not group or | ||||
284 | world writeable. | ||||
285 | |||||
286 | =back | ||||
287 | |||||
288 | =head1 AUTHORS | ||||
289 | |||||
290 | Ivan Kohler <ivan-netssh_pod@420.am> | ||||
291 | |||||
292 | Assistance wanted - this module could really use a maintainer with enough time | ||||
293 | to at least review and apply more patches. Or the module should just be | ||||
294 | deprecated in favor of Net::SSH::Expect or made into an ::Any style | ||||
295 | compatibility wrapper that uses whatver implementation is avaialble | ||||
296 | (Net::SSH2, Net::SSH::Perl or shelling out like the module does now). Please | ||||
297 | email Ivan if you are interested in helping. | ||||
298 | |||||
299 | John Harrison <japh@in-ta.net> contributed an example for the documentation. | ||||
300 | |||||
301 | Martin Langhoff <martin@cwa.co.nz> contributed the ssh_cmd command, and | ||||
302 | Jeff Finucane <jeff@cmh.net> updated it and took care of the 0.04 release. | ||||
303 | |||||
304 | Anthony Awtrey <tony@awtrey.com> contributed a fix for those still using | ||||
305 | OpenSSH v1. | ||||
306 | |||||
307 | Thanks to terrence brannon <tbone@directsynergy.com> for the documentation in | ||||
308 | the GENERATING AND USING SSH KEYS section. | ||||
309 | |||||
310 | =head1 COPYRIGHT | ||||
311 | |||||
312 | Copyright (c) 2004 Ivan Kohler. | ||||
313 | Copyright (c) 2007-2008 Freeside Internet Services, Inc. | ||||
314 | All rights reserved. | ||||
315 | This program is free software; you can redistribute it and/or modify it under | ||||
316 | the same terms as Perl itself. | ||||
317 | |||||
318 | =head1 BUGS | ||||
319 | |||||
320 | Not OO. | ||||
321 | |||||
322 | Look at IPC::Session (also fsh, well now the native SSH "master mode" stuff) | ||||
323 | |||||
324 | =head1 SEE ALSO | ||||
325 | |||||
326 | For a perl implementation that does not require the system B<ssh> command, see | ||||
327 | L<Net::SSH::Perl> instead. | ||||
328 | |||||
329 | For a wrapper version that allows you to use passwords, see L<Net::SSH::Expect> | ||||
330 | instead. | ||||
331 | |||||
332 | For another non-forking version that uses the libssh2 library, see | ||||
333 | L<Net::SSH2>. | ||||
334 | |||||
335 | For a way to execute remote Perl code over an ssh connection see | ||||
336 | L<IPC::PerlSSH>. | ||||
337 | |||||
338 | ssh-keygen(1), ssh(1), L<IO::File>, L<IPC::Open2>, L<IPC::Open3> | ||||
339 | |||||
340 | =cut | ||||
341 | |||||
342 | 1 | 5µs | 1; | ||
343 |