Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages


home | help
Net::OpenSSH(3)	      User Contributed Perl Documentation      Net::OpenSSH(3)

       Net::OpenSSH - Perl SSH client package implemented on top of OpenSSH

	 use Net::OpenSSH;

	 my $ssh = Net::OpenSSH->new($host);
	 $ssh->error and
	   die "Couldn't establish SSH connection: ". $ssh->error;

	 $ssh->system("ls /tmp") or
	   die "remote command failed: " . $ssh->error;

	 my @ls	= $ssh->capture("ls");
	 $ssh->error and
	   die "remote ls command failed: " . $ssh->error;

	 my ($out, $err) = $ssh->capture2("find	/root");
	 $ssh->error and
	   die "remote find command failed: " .	$ssh->error;

	 my ($rin, $pid) = $ssh->pipe_in("cat >/tmp/foo") or
	   die "pipe_in	method failed: " . $ssh->error;

	 print $rin "hello\n";
	 close $rin;

	 my ($rout, $pid) = $ssh->pipe_out("cat	/tmp/foo") or
	   die "pipe_out method	failed:	" . $ssh->error;

	 while (<$rout>) { print }
	 close $rout;

	 my ($in, $out ,$pid) =	$ssh->open2("foo");
	 my ($pty, $pid) = $ssh->open2pty("foo");
	 my ($in, $out,	$err, $pid) = $ssh->open3("foo");
	 my ($pty, $err, $pid) = $ssh->open3pty("login");

	 my $sftp = $ssh->sftp();
	 $sftp->error and die "SFTP failed: " .	$sftp->error;

       Net::OpenSSH is a secure	shell client package implemented on top	of
       OpenSSH binary client ("ssh").

   Under the hood
       This package is implemented around the multiplexing feature found in
       later versions of OpenSSH. That feature allows one to run several
       sessions	over a single SSH connection (OpenSSH 4.1 was the first	one to
       provide all the required	functionality).

       When a new Net::OpenSSH object is created, the OpenSSH "ssh" client is
       run in master mode, establishing	a persistent (for the lifetime of the
       object) connection to the server.

       Then, every time	a new operation	is requested a new "ssh" process is
       started in slave	mode, effectively reusing the master SSH connection to
       send the	request	to the remote side.

   Net::OpenSSH	Vs. Net::SSH::.* modules
       Why should you use Net::OpenSSH instead of any of the other Perl	SSH
       clients available?

       Well, this is my	(biased) opinion:

       Net::SSH::Perl is not well maintained nowadays (update: a new
       maintainer has stepped in so this situation could change!!!), requires
       a bunch of modules (some	of them	very difficult to install) to be
       acceptably efficient and	has an API that	is limited in some ways.

       Net::SSH2 is much better	than Net::SSH::Perl, but not completely	stable
       yet. It can be very difficult to	install	on some	specific operating
       systems and its API is also limited, in the same	way as Net::SSH::Perl.

       Using Net::SSH::Expect, in general, is a	bad idea. Handling interaction
       with a shell via	Expect in a generic way	just can not be	reliably done.

       Net::SSH	is just	a wrapper around any SSH binary	commands available on
       the machine. It can be very slow	as they	establish a new	SSH connection
       for every operation performed.

       In comparison, Net::OpenSSH is a	pure perl module that does not have
       any mandatory dependencies (obviously, besides requiring	OpenSSH

       Net::OpenSSH has	a very perlish interface. Most operations are
       performed in a fashion very similar to that of the Perl builtins	and
       common modules (e.g. IPC::Open2).

       It is also very fast. The overhead introduced by	launching a new	ssh
       process for every operation is not appreciable (at least	on my Linux
       box). The bottleneck is the latency intrinsic to	the protocol, so
       Net::OpenSSH is probably	as fast	as an SSH client can be.

       Being based on OpenSSH is also an advantage: a proved, stable, secure
       (to paranoid levels), inseparably and well maintained implementation of
       the SSH protocol	is used.

       On the other hand, Net::OpenSSH does not	work on	Windows, not even
       under Cygwin.

       Net::OpenSSH specifically requires the OpenSSH SSH client (AFAIK, the
       multiplexing feature is not available from any other SSH	client).
       However,	note that it will interact with	any server software, not just
       servers running OpenSSH "sshd".

       For password authentication, IO::Pty has	to be installed. Other modules
       and binaries are	also required to implement specific functionality (for
       instance	Net::SFTP::Foreign, Expect or rsync(1)).

       Net::OpenSSH and	Net::SSH2 do not support version 1 of the SSH

   Optional arguments
       Almost all methods in this package accept as first argument an optional
       reference to a hash containing parameters ("\%opts"). For instance,
       these two method	calls are equivalent:

	 my $out1 = $ssh->capture(@cmd);
	 my $out2 = $ssh->capture({}, @cmd);

   Error handling
       Most methods return undef (or an	empty list) to indicate	failure.

       The "error" method can always be	used to	explicitly check for errors.
       For instance:

	 my ($output, $errput) = $ssh->capture2({timeout => 1},	"find /");
	 $ssh->error and die "ssh failed: " . $ssh->error;

   Net::OpenSSH	methods
       These are the methods provided by the package:

       Net::OpenSSH->new($host,	%opts)
	   Creates a new SSH master connection

	   $host can be	a hostname or an IP address. It	may also contain the
	   name	of the user, her password and the TCP port number where	the
	   server is listening:

	      my $ssh1 = Net::OpenSSH->new('');
	      my $ssh2 = Net::OpenSSH->new('');
	      my $ssh3 = Net::OpenSSH->new('jsmith@2001:db8::1428:57ab'); # IPv6

	   IPv6	addresses may optionally be enclosed in	brackets:

	      my $ssh4 = Net::OpenSSH->new('jsmith@[::1]:1022');

	   This	method always succeeds in returning a new object. Error
	   checking has	to be performed	explicitly afterwards:

	     my	$ssh = Net::OpenSSH->new($host,	%opts);
	     $ssh->error and die "Can't	ssh to $host: "	. $ssh->error;

	   If you have problems	getting	Net::OpenSSH to	connect	to the remote
	   host	read the troubleshooting chapter near the end of this

	   Accepted options:

	   user	=> $user_name
	       Login name

	   port	=> $port
	       TCP port	number where the server	is running

	   password => $password
	       User given password for authentication.

	       Note that using password	authentication in automated scripts is
	       a very bad idea.	When possible, you should use public key
	       authentication instead.

	   passphrase => $passphrase
	       Uses given passphrase to	open private key.

	   key_path => $private_key_path
	       Uses the	key stored on the given	file path for authentication.

	   gateway => $gateway
	       If the given argument is	a gateway object as returned by
	       "find_gateway" in Net::OpenSSH::Gateway method, use it to
	       connect to the remote host.

	       If it is	a hash reference, call the "find_gateway" method

	       For instance, the following code	fragments are equivalent:

		 my $gateway = Net::OpenSSH::Gateway->find_gateway(
			 proxy => '');
		 $ssh =	Net::OpenSSH->new($host, gateway => $gateway);


		 $ssh =	Net::OpenSSH->new($host,
			 gateway => { proxy => ''});

	   proxy_command => $proxy_command
	       Use the given command to	establish the connection to the	remote
	       host (see "ProxyCommand"	on ssh_config(5)).

	   batch_mode => 1
	       Disables	querying the user for password and passphrases.

	   ctl_dir => $path
	       Directory where the SSH master control socket will be created.

	       This directory and its parents must be writable only by the
	       current effective user or root, otherwise the connection	will
	       be aborted to avoid insecure operation.

	       By default "~/.libnet-openssh-perl" is used.

	   ssh_cmd => $cmd
	       Name or full path to OpenSSH "ssh" binary. For instance:

		 my $ssh = Net::OpenSSH->new($host, ssh_cmd => '/opt/OpenSSH/bin/ssh');

	   scp_cmd => $cmd
	       Name or full path to OpenSSH "scp" binary.

	       By default it is	inferred from the "ssh"	one.

	   rsync_cmd =>	$cmd
	       Name or full path to "rsync" binary. Defaults to	"rsync".

	   remote_shell	=> $name
	       Name of the remote shell. Used to select	the argument quoter

	   timeout => $timeout
	       Maximum acceptable time that can	elapse without network traffic
	       or any other event happening on methods that are	not immediate
	       (for instance, when establishing	the master SSH connection or
	       inside methods "capture", "system", "scp_get", etc.).

	       See also	"Timeouts".

	   kill_ssh_on_timeout => 1
	       This option tells Net::OpenSSH to kill the local	slave SSH
	       process when some operation times out.

	       See also	"Timeouts".

	   strict_mode => 0
	       By default, the connection will be aborted if the path to the
	       socket used for multiplexing is found to	be non-secure (for
	       instance, when any of the parent	directories is writable	by
	       other users).

	       This option can be used to disable that feature.	Use with

	   async => 1
	       By default, the constructor waits until the multiplexing	socket
	       is available. That option can be	used to	defer the waiting
	       until the socket	is actually used.

	       For instance, the following code	connects to several remote
	       machines	in parallel:

		 my (%ssh, %ls);
		 # multiple connections	are established	in parallel:
		 for my	$host (@hosts) {
		     $ssh{$host} = Net::OpenSSH->new($host, async => 1);
		 # then	to run some command in all the hosts (sequentially):
		 for my	$host (@hosts) {
		     $ssh{$host}->system('ls /');

	   connect => 0
	       Do not launch the master	SSH process yet.

	   master_opts => [...]
	       Additional options to pass to the "ssh" command when
	       establishing the	master connection. For instance:

		 my $ssh = Net::OpenSSH->new($host,
		     master_opts => [-o	=> "ProxyCommand corkscrew httpproxy 8080 $host"]);

	   default_ssh_opts => [...]
	       Default slave SSH command line options for "open_ex" and
	       derived methods.

	       For instance:

		 my $ssh = Net::OpenSSH->new($host,
		     default_ssh_opts => [-o =>	"ConnectionAttempts=0"]);

	   forward_agent => 1
	       Enables forwarding of the authentication	agent.

	       This option can not be used when	passing	a passphrase (via
	       "passphrase") to	unlock the login private key.

	       Note that Net::OpenSSH will not run "ssh-agent" for you.	This
	       has to be done ahead of time and	the environment	variable
	       "SSH_AUTH_SOCK" set pointing to the proper place.

	   forward_X11 => 1
	       Enables forwarding of the X11 protocol

	   default_stdin_fh => $fh
	   default_stdout_fh =>	$fh
	   default_stderr_fh =>	$fh
	       Default I/O streams for "open_ex" and derived methods
	       (currently, that	means any method but "pipe_in" and "pipe_out"
	       and I plan to remove those exceptions soon!).

	       For instance:

		 open my $stderr_fh, '>>', '/tmp/$host.err' or die ...;
		 open my $stdout_fh, '>>', '/tmp/$host.log' or die ...;

		 my $ssh = Net::OpenSSH->new($host, default_stderr_fh => $stderr_fh,
						    default_stdout_fh => $stdout_fh);
		 $ssh->error and die "SSH connection failed: " . $ssh->error;

		 $ssh->scp_put("/foo/bar*", "/tmp")
		   or die "scp failed: " . $ssh->error;

	   default_stdin_file =	$fn
	   default_stdout_file = $fn
	   default_stderr_file = $fn
	       Opens the given file names and use them as the defaults.

	   master_stdout_fh => $fh
	   master_stderr_fh => $fh
	       Redirect	corresponding stdio streams of the master SSH process
	       to given	filehandles.

	   master_stdout_discard => $bool
	   master_stderr_discard => $bool
	       Discard corresponding stdio streams.

	   expand_vars => $bool
	       Activates variable expansion inside command arguments and file

	       See "Variable expansion"	below.

	   vars	=> \%vars
	       Initial set of variables.

	   external_master => 1
	       Instead of launching a new OpenSSH client in master mode, the
	       module tries to reuse an	already	existent one. "ctl_path" must
	       also be passed when this	option is set. See also


		 $ssh =	Net::OpenSSH->new('foo', external_master => 1, ctl_path	= $path);

	       When "external_master" is set, the hostname argument becomes
	       optional	( is passed to OpenSSH which does not use it at

	   default_encoding => $encoding
	   default_stream_encoding => $encoding
	   default_argument_encoding =>	$encoding
	       Set default encodings. See "Data	encoding".

	   password_prompt => $string
	   password_prompt => $re
	       By default, when	using password authentication, the module
	       expects the remote side to send a password prompt matching

	       This option can be used to override that	default	for the	rare
	       cases when a different prompt is	used.


		  password_prompt => ']'; # no need to escape ']'
		  password_prompt => qr/[:?>]/;

	   login_handler => \&custom_login_handler
	       Some remote SSH server may require a custom
	       login/authentication interaction	not natively supported by
	       Net::OpenSSH. In	that cases, you	can use	this option to replace
	       the default login logic.

	       The callback will be invoked repeatedly as
	       "custom_login_handler($ssh, $pty, $data)" where $ssh is the
	       current Net::OpenSSH object, "pty" a IO::Pty object attached to
	       the slave "ssh" process tty and $data a reference to an scalar
	       you can use at will.

	       The login handler must return 1 after the login process has
	       completed successfully or 0 in case it still needs to do
	       something else. If some error happens, it must die.

	       Note, that blocking operations should not be performed inside
	       the login handler (at least if you want the "async" and
	       "timeout" features to work).

	       See also	the sample script "" in	the "samples"

	       Usage of	this option is incompatible with the "password"	and
	       "passphrase" options, you will have to handle password or
	       passphrases from	the custom handler yourself.

	   master_setpgrp => 1
	       When this option	is set,	the master process is run as a
	       different process group.	As a consequence it will not die when
	       the user	presses	Ctrl-C at the terminal.

	       In order	to allow the master SSH	process	to request any
	       information from	the user, the module may set it	as the
	       terminal	controlling process while the connection is
	       established (using "tcsetpgrp" in POSIX). Afterwards, the
	       terminal	controlling process is reset.

	       This feature is highly experimental. Report any problems	you
	       may find, please.

	   Returns the error condition for the last performed operation.

	   The returned	value is a dualvar as $! (see "$!" in perlvar) that
	   renders an informative message when used in string context or an
	   error number	in numeric context (error codes	appear in

	   Return the corresponding SSH	login parameters.

	   Returns the path to the socket where	the OpenSSH master process
	   listens for new multiplexed connections.

       ($in, $out, $err, $pid) = $ssh->open_ex(\%opts, @cmd)
	   Note: this is a low level method which, probably, you do not	need
	   to use!

	   That	method starts the command @cmd on the remote machine creating
	   new pipes for the IO	channels as specified on the %opts hash.

	   If @cmd is omitted, the remote user shell is	run.

	   Returns four	values,	the first three	($in, $out and $err)
	   correspond to the local side	of the pipes created (they can be
	   undef) and the fourth ($pid)	to the PID of the new SSH slave
	   process. An empty list is returned on failure.

	   Note	that "waitpid" has to be used afterwards to reap the slave SSH

	   Accepted options:

	   stdin_pipe => 1
	       Creates a new pipe and connects the reading side	to the stdin
	       stream of the remote process. The writing side is returned as
	       the first value ($in).

	   stdin_pty =>	1
	       Similar to "stdin_pipe",	but instead of a regular pipe it uses
	       a pseudo-tty (pty).

	       Note that on some operating systems (e.g. HP-UX,	AIX), ttys are
	       not reliable. They can overflow when large chunks are written
	       or when data is written faster than it is read.

	   stdin_fh => $fh
	       Duplicates $fh and uses it as the stdin stream of the remote

	   stdin_file => $filename
	   stdin_file => \@open_args
	       Opens the file of the given name	for reading and	uses it	as the
	       remote process stdin stream.

	       If an array reference is	passed its contents are	used as	the
	       arguments for the underlying open call. For instance:

		 $ssh->system({stdin_file => ['-|', 'gzip -c -d	file.gz']}, $rcmd);

	   stdin_discard => 1
	       Uses /dev/null as the remote process stdin stream.

	   stdout_pipe => 1
	       Creates a new pipe and connects the writing side	to the stdout
	       stream of the remote process. The reading side is returned as
	       the second value	($out).

	   stdout_pty => 1
	       Connects	the stdout stream of the remote	process	to the pseudo-
	       pty. This option	requires "stdin_pty" to	be also	set.

	   stdout_fh =>	$fh
	       Duplicates $fh and uses it as the stdout	stream of the remote

	   stdout_file => $filename
	   stdout_file => \@open_args
	       Opens the file of the given filename and	redirect stdout	there.

	   stdout_discard => 1
	       Uses /dev/null as the remote process stdout stream.

	   stdinout_socket => 1
	       Creates a new socketpair, attaches the stdin an stdout streams
	       of the slave SSH	process	to one end and returns the other as
	       the first value ($in) and undef for the second ($out).


		 my ($socket, undef, undef, $pid) = $ssh->open_ex({stdinout_socket => 1},
								  '/bin/netcat $dest');

	       See also	"open2socket".

	   stdinout_dpipe => $cmd
	   stdinout_dpipe => \@cmd
	       Runs the	given command locally attaching	its stdio streams to
	       those of	the remote SSH command.	Conceptually it	is equivalent
	       to the dpipe(1) shell command.

	   stderr_pipe => 1
	       Creates a new pipe and connects the writing side	to the stderr
	       stream of the remote process. The reading side is returned as
	       the third value ($err).


		 my $pid = $ssh->open_ex({stdinout_dpipe => 'vncviewer -stdio'},
					 x11vnc	=> '-inetd');

	   stderr_fh =>	$fh
	       Duplicates $fh and uses it as the stderr	stream of the remote

	   stderr_file => $filename
	       Opens the file of the given name	and redirects stderr there.

	   stderr_to_stdout => 1
	       Makes stderr point to stdout.

	   tty => $bool
	       Tells "ssh" to allocate a pseudo-tty for	the remote process. By
	       default,	a tty is allocated if remote command stdin stream is
	       attached	to a tty.

	       When this flag is set and stdin is not attached to a tty, the
	       ssh master and slave processes may generate spurious warnings
	       about failed tty	operations. This is caused by a	bug present in
	       older versions of OpenSSH.

	   close_slave_pty => 0
	       When a pseudo pty is used for the stdin stream, the slave side
	       is automatically	closed on the parent process after forking the
	       ssh command.

	       This option disables that feature, so that the slave pty	can be
	       accessed	on the parent process as "$pty->slave".	It will	have
	       to be explicitly	closed (see IO::Pty)

	   quote_args => $bool
	       See "Shell quoting" below.

	   remote_shell	=> $shell
	       Sets the	remote shell. Allows one to change the argument
	       quoting mechanism in a per-command fashion.

	       This may	be useful when interacting with	a Windows machine
	       where argument parsing may be done at the command level in
	       custom ways.


		 $ssh->system({remote_shell => 'MSWin'}, echo => $line);
		 $ssh->system({remote_shell => 'MSCmd,MSWin'}, type => $file);

	   forward_agent => $bool
	       Enables/disables	forwarding of the authentication agent.

	       This option can only be used when agent forwarding has been
	       previously requested on the constructor.

	   forward_X11 => $bool
	       Enables/disables	forwarding of the X11 protocol.

	       This option can only be used when X11 forwarding	has been
	       previously requested on the constructor.

	   ssh_opts => \@opts
	       List of extra options for the "ssh" command.

	       This feature should be used with	care, as the given options are
	       not checked in any way by the module, and they could interfere
	       with it.

	   tunnel => $bool
	       Instead of executing a command in the remote host, this option
	       instruct	Net::OpenSSH to	create a TCP tunnel. The arguments
	       become the target IP and	port or	the remote path	for an Unix


		 my ($in, $out,	undef, $pid) = $ssh->open_ex({tunnel =>	1}, $IP, $port);
		 my ($in, $out,	undef, $pid) = $ssh->open_ex({tunnel =>	1}, $socket_path);

	       See also	"Tunnels".

	   encoding => $encoding
	   argument_encoding =>	$encoding
	       Set encodings. See "Data	encoding".

	   Usage example:

	     # similar to IPC::Open2 open2 function:
	     my	($in_pipe, $out_pipe, undef, $pid) =
		 $ssh->open_ex(	{ stdin_pipe =>	1,
				  stdout_pipe => 1 },
				@cmd )
		 or die	"open_ex failed: " . $ssh->error;
	     # do some IO through $in/$out
	     # ...

       setpgrp => 1
	   Calls "setpgrp" after forking the child process. As a result	it
	   will	not die	when the user presses Ctrl+C at	the console. See also
	   "setpgrp" in	perlfunc.

	   Using this option without also setting "master_setpgrp" on the
	   constructor call is mostly useless as the signal will be delivered
	   to the master process and all the remote commands aborted.

	   This	feature	is experimental.

       $ssh->system(\%opts, @cmd)
	   Runs	the command @cmd on the	remote machine.

	   Returns true	on success, undef otherwise.

	   The error status is set to "OSSH_SLAVE_CMD_FAILED" when the remote
	   command exits with a	non zero code (the code	is available from $?,
	   see "$?" in perlvar).


	     $ssh->system('ls -R /')
	       or die "ls failed: " . $ssh->error";

	   As for "system" builtin, "SIGINT" and "SIGQUIT" signals are
	   blocked.  (see "system" in perlfunc). Also, setting $SIG{CHLD} to
	   "IGNORE" or to a custom signal handler will interfere with this

	   Accepted options:

	   stdin_data => $input
	   stdin_data => \@input
	       Sends the given data through the	stdin stream to	the remote

	       For example, the	following code creates a file on the remote

		 $ssh->system({stdin_data => \@data}, "cat >/tmp/foo")
		   or die "unable to write file: " . $ssh->error;

	   timeout => $timeout
	       The operation is	aborted	after $timeout seconds elapsed without
	       network activity.

	       See also	"Timeouts".

	   async => 1
	       Does not	wait for the child process to exit. The	PID of the new
	       process is returned.

	       Note that when this option is combined with "stdin_data", the
	       given data will be transferred to the remote side before
	       returning control to the	caller.

	       See also	the "spawn" method documentation below.

	   stdin_fh => $fh
	   stdin_discard => $bool
	   stdout_fh =>	$fh
	   stdout_discard => $bool
	   stderr_fh =>	$fh
	   stderr_discard => $bool
	   stderr_to_stdout => $bool
	   stdinout_dpipe => $cmd
	   tty => $bool
	       See the "open_ex" method	documentation for an explanation of
	       these options.

       $ok = $ssh->test(\%opts,	@cmd);
	   Runs	the given command and returns its success/failure exit status
	   as 1	or 0 respectively. Returns undef when something	goes wrong in
	   the SSH layer.

	   Error status	is not set to OSSH_SLAVE_CMD_FAILED when the remote
	   command exits with a	non-zero code.

	   By default this method discards the remote command "stdout" and
	   "sterr" streams.

	   Usage example:

	     if	($ssh->test(ps => -C =>	$executable)) {
	       say "$executable	is running on remote machine"
	     else {
	       die "something got wrong: ". $ssh->error	if $ssh->error;

	       say "$executable	is not running on remote machine"

	   This	method support the same	set of options as "system", except
	   "async" and "tunnel".

       $output = $ssh->capture(\%opts, @cmd);
       @output = $ssh->capture(\%opts, @cmd);
	   This	method is conceptually equivalent to the perl backquote
	   operator (e.g. "`ls`"): it runs the command on the remote machine
	   and captures	its output.

	   In scalar context returns the output	as a scalar. In	list context
	   returns the output broken into lines	(it honors $/, see "$/"	in

	   The exit status of the remote command is returned in	$?.

	   When	an error happens while capturing (for instance,	the operation
	   times out), the partial captured output will	be returned. Error
	   conditions have to be explicitly checked using the "error" method.
	   For instance:

	     my	$output	= $ssh->capture({ timeout => 10	},
					"echo hello; sleep 20; echo bye");
	     $ssh->error and
		 warn "operation didn't	complete successfully: ". $ssh->error;
	     print $output;

	   Setting $SIG{CHLD} to a custom signal handler or to "IGNORE"	will
	   interfere with this method.

	   Accepted options:

	   stdin_data => $input
	   stdin_data => \@input
	   timeout => $timeout
	       See "Timeouts".

	   stdin_fh => $fh
	   stdin_discard => $bool
	   stderr_fh =>	$fh
	   stderr_discard => $bool
	   stderr_to_stdout => $bool
	   tty => $bool
	       See the "open_ex" method	documentation for an explanation of
	       these options.

       ($output, $errput) = $ssh->capture2(\%opts, @cmd)
	   captures the	output sent to both stdout and stderr by @cmd on the
	   remote machine.

	   Setting $SIG{CHLD} to a custom signal handler or to "IGNORE"	will
	   also	interfere with this method.

	   The accepted	options	are:

	   stdin_data => $input
	   stdin_data => \@input
	       See the "system"	method documentation for an explanation	of
	       these options.

	   timeout => $timeout
	       See "Timeouts".

	   stdin_fh => $fh
	   stdin_discard => $bool
	   tty => $bool
	       See the "open_ex" method	documentation for an explanation of
	       these options.

       ($in, $pid) = $ssh->pipe_in(\%opts, @cmd)
	   This	method is similar to the following Perl	"open" call

	     $pid = open $in, '|-', @cmd

	   but running @cmd on the remote machine (see "open" in perlfunc).

	   No options are currently accepted.

	   There is no need to perform a waitpid on the	returned PID as	it
	   will	be done	automatically by perl when $in is closed.


	     my	($in, $pid) = $ssh->pipe_in('cat >/tmp/fpp')
		 or die	"pipe_in failed: " . $ssh->error;
	     print $in $_ for @data;
	     close $in or die "close failed";

       ($out, $pid) = $ssh->pipe_out(\%opts, @cmd)
	   Reciprocal to previous method, it is	equivalent to

	     $pid = open $out, '-|', @cmd

	   running @cmd	on the remote machine.

	   No options are currently accepted.

       ($in, $out, $pid) = $ssh->open2(\%opts, @cmd)
       ($pty, $pid) = $ssh->open2pty(\%opts, @cmd)
       ($socket, $pid) = $ssh->open2socket(\%opts, @cmd)
       ($in, $out, $err, $pid) = $ssh->open3(\%opts, @cmd)
       ($pty, $err, $pid) = $ssh->open3pty(\%opts, @cmd)
	   Shortcuts around "open_ex" method.

       $pid = $ssh->spawn(\%opts, @_)
	   Another "open_ex" shortcut, it launches a new remote	process	in the
	   background and returns the PID of the local slave SSH process.

	   At some later point in your script, "waitpid" should	be called on
	   the returned	PID in order to	reap the slave SSH process.

	   For instance, you can run some command on several hosts in parallel
	   with	the following code:

	     my	%conn =	map { $_ => Net::OpenSSH->new($_, async	=> 1) }	@hosts;
	     my	@pid;
	     for my $host (@hosts) {
		 open my($fh), '>', "/tmp/out-$host.txt"
		   or die "unable to create file: $!";
		 push @pid, $conn{$host}->spawn({stdout_fh => $fh}, $cmd);

	     waitpid($_, 0) for	@pid;

	   Note	that "spawn" should not	be used	to start detached remote
	   processes that may survive the local	program	(see also the "FAQ"
	   about running remote	processes detached).

       ($socket, $pid) = $ssh->open_tunnel(\%opts, $dest_host, $port)
       ($socket, $pid) = $ssh->open_tunnel(\%opts, $socket_path)
	   Similar to "open2socket", but instead of running a command, it
	   opens a TCP tunnel to the given address. See	also "Tunnels".

       $out = $ssh->capture_tunnel(\%opts, $dest_host, $port)
       @out = $ssh->capture_tunnel(\%opts, $dest_host, $port)
	   Similar to "capture", but instead of	running	a command, it opens a
	   TCP tunnel.


	     $out = $ssh->capture_tunnel({stdin_data =>	join("\r\n",
							     "GET / HTTP/1.0",
							     "", "") },
					 '', 80)

	   See also "Tunnels".

       $ssh->scp_get(\%opts, $remote1, $remote2,..., $local_dir_or_file)
       $ssh->scp_put(\%opts, $local, $local2,..., $remote_dir_or_file)
	   These two methods are wrappers around the "scp" command that	allow
	   transfers of	files to/from the remote host using the	existing SSH
	   master connection.

	   When	transferring several files, the	target argument	must point to
	   an existing directory. If only one file is to be transferred, the
	   target argument can be a directory or a file	name or	can be
	   omitted. For	instance:

	     $ssh->scp_get({glob => 1},	'/var/tmp/foo*', '/var/tmp/bar*', '/tmp');

	   Both	"scp_get" and "scp_put"	methods	return a true value when all
	   the files are transferred correctly,	otherwise they return undef.

	   Accepted options:

	   quiet => 0
	       By default, "scp" is called with	the quiet flag "-q" enabled in
	       order to	suppress progress information. This option allows one
	       to re-enable the	progress indication bar.

	   verbose => 1
	       Calls "scp" with	the "-v" flag.

	   recursive =>	1
	       Copies files and	directories recursively.

	   glob	=> 1
	       Enables expansion of shell metacharacters in the	sources	list
	       so that wildcards can be	used to	select files.

	   glob_flags => $flags
	       Second argument passed to File::Glob::bsd_glob function.	Only
	       available for "scp_put" method.

	   copy_attrs => 1
	       Copies modification and access times and	modes from the
	       original	files.

	   bwlimit => $Kbits
	       Limits the used bandwidth, specified in Kbit/s.

	   timeout => $secs
	       The transfer is aborted if the connection does not finish
	       before the given	timeout	elapses. See also "Timeouts".

	   async => 1
	       Does not	wait for the "scp" command to finish. When this	option
	       is used,	the method returns the PID of the child	"scp" process.

	       For instance, it	is possible to transfer	files to several hosts
	       in parallel as follows:

		 use Errno;
		 my (%pid, %ssh);
		 for my	$host (@hosts) {
		   $ssh{$host} = Net::OpenSSH->new($host, async	=> 1);
		 for my	$host (@hosts) {
		   $pid{$host} = $ssh{$host}->scp_put({async =>	1}, $local_fn, $remote_fn)
		     or	warn "scp_put to $host failed: " . $ssh{$host}->error .	"\n";
		 for my	$host (@hosts) {
		   if (my $pid = $pid{$host}) {
		     if	(waitpid($pid, 0) > 0) {
		       my $exit	= ($? >> 8);
		       $exit and warn "transfer	of file	to $host failed	($exit)\n";
		     else {
		       redo if ($! == EINTR);
		       warn "waitpid($pid) failed: $!\n";

	   stdout_fh =>	$fh
	   stderr_fh =>	$fh
	   stderr_to_stdout => 1
	       These options are passed	unchanged to method "open_ex",
	       allowing	capture	of the output of the "scp" program.

	       Note that "scp" will not	generate progress reports unless its
	       stdout stream is	attached to a tty.

	   ssh_opts => \@opts
	       List of extra options for the "ssh" command.

	       This feature should be used with	care, as the given options are
	       not checked in any way by the module, and they could interfere
	       with it.

       $ssh->rsync_get(\%opts, $remote1, $remote2,..., $local_dir_or_file)
       $ssh->rsync_put(\%opts, $local1,	$local2,..., $remote_dir_or_file)
	   These methods use "rsync" over SSH to transfer files	from/to	the
	   remote machine.

	   They	accept the same	set of options as the "scp" ones.

	   Any unrecognized option will	be passed as an	argument to the
	   "rsync" command (see	rsync(1)). Underscores can be used instead of
	   dashes in "rsync" option names.

	   For instance:

	     $ssh->rsync_get({exclude => '*~',
			      verbose => 1,
			      safe_links => 1},
			     '/remote/dir', '/local/dir');

       $sftp = $ssh->sftp(%sftp_opts)
	   Creates a new Net::SFTP::Foreign object for SFTP interaction	that
	   runs	through	the ssh	master connection.

       @call = $ssh->make_remote_command(\%opts, @cmd)
       $call = $ssh->make_remote_command(\%opts, @cmd)
	   This	method returns the arguments required to execute a command on
	   the remote machine via SSH. For instance:

	     my	@call =	$ssh->make_remote_command(ls =>	"/var/log");
	     system @call;

	   In scalar context, returns the arguments quoted and joined into one

	     my	$remote	= $ssh->make_remote_comand("cd /tmp/ &&	tar xf -");
	     system "tar cf - .	| $remote";

	   The options accepted	are as follows:

	   tty => $bool
	       Enables/disables	allocation of a	tty on the remote side.

	   forward_agent => $bool
	       Enables/disables	forwarding of authentication agent.

	       This option can only be used when agent forwarding has been
	       previously requested on the constructor.

	   tunnel => 1
	       Return a	command	to create a connection to some TCP server
	       reachable from the remote host. In that case the	arguments are
	       the destination address and port. For instance:

		 $cmd =	$ssh->make_remote_command({tunnel => 1}, $host,	$port);

	   When	the connection has been	established by calling the constructor
	   with	the "async" option, this call allows one to advance the

	   If $async is	true, it will perform any work that can	be done
	   immediately without waiting (for instance, entering the password or
	   checking for	the existence of the multiplexing socket) and then
	   return. If a	false value is given, it will finalize the connection
	   process and wait until the multiplexing socket is available.

	   It returns a	true value after the connection	has been successfully
	   established.	False is returned if the connection process fails or
	   if it has not yet completed (then, the "error" method can be	used
	   to distinguish between both cases).

	   From	version	0.64 upwards, undef is returned	when the master	is
	   still in an unstable	state (login, killing, etc.) and 0 when	it is
	   in a	stable state (running, stopped or gone).

	   This	method runs several checks to ensure that the master
	   connection is still alive.

	   Returns the list of arguments quoted	so that	they will be restored
	   to their original form when parsed by the remote shell.

	   In scalar context returns the list of arguments quoted and joined.

	   Usually this	task is	done automatically by the module. See "Shell
	   quoting" below.

	   This	method can also	be used	as a class method.


	     my	$quoted_args = Net::OpenSSH->shell_quote(@args);
	     system('ssh', '--', $host,	$quoted_args);

	   This	method is like the previous "shell_quote" but leaves wildcard
	   characters unquoted.

	   It can be used as a class method also.

	   Enables/disables variable expansion feature (see "Variable

	   Returns current state of variable expansion feature.

       $ssh->set_var($name, $value)
       $ssh->get_var($name, $value)
	   These methods allow one to change and to retrieve the value of the
	   given name.

	   Returns the PID of the master SSH process

	   This	methods	allows one to tell the module that the master process
	   has exited when we get its PID from some external wait or waitpid
	   call. For instance:

	     my	$ssh = Net::OpenSSH->new('foo',	async => 1);

	     # create new processes
	     # ...

	     # rip them...
	     my	$master_pid = $ssh->master_pid;
	     while ((my	$pid = wait) > 0) {
	       if ($pid	== $master_pid)	{

	   If your program rips	the master process and this method is not
	   called, the OS could	reassign the PID to a new unrelated process
	   and the module would	try to kill it at object destruction time.

	   Shuts down the SSH connection.

	   Usually, you	don't need to call this	method explicitly, but just
	   let the Net::OpenSSH	object go out of scope.

	   If "async" is true, it doesn't wait for the SSH connection to
	   terminate. In that case, "wait_for_master" must be called
	   repeatedly until the	shutdown sequence terminates (See the
	   "AnyEvent" integration section bellow).

       $pid = $ssh->sshfs_import(\%opts, $remote_fs, $local_mnt_point)
       $pid = $ssh->sshfs_export(\%opts, $local_fs, $remote_mnt_point)
	   These methods use sshfs(1) to import	or export a file system
	   through the SSH connection.

	   They	return the $pid	of the "sshfs" process or of the slave "ssh"
	   process used	to proxy it. Killing that process unmounts the file
	   system, though, it may be probably better to	use fusermount(1).

	   The options accepted	are as follows:

	   ssh_opts => \@ssh_opts
	       Options passed to the slave "ssh" process.

	   sshfs_opts => \@sshfs_opts
	       Options passed to the "sshfs" command. For instance, to mount
	       the file	system in read-only mode:

		 my $pid = $ssh->sshfs_export({sshfs_opts => [-o => 'ro']},
					      "/", "/mnt/foo");

	   Note	that this command requires a recent version of "sshfs" to work
	   (at the time	of writing, it requires	the yet	unreleased version
	   available from the FUSE git repository!).

	   See also the	sshfs(1) man page and the "sshfs" and FUSE web sites
	   at <> and
	   <> respectively.

       $or = $ssh->object_remote(@args)
	   Returns an Object::Remote::Connection instance running on top of
	   the Net::OpenSSH connection.


	      my $or = $ssh->object_remote;
	      my $hostname = Sys::Hostname->can::on($or, 'hostname');
	      say $hostname->();

	   See also Object::Remote.

       $any = $ssh->any(%opts)
	   Wraps the current object inside a Net::SSH::Any one.


	     my	$any = $ssh->any;
	     my	$content = $any->scp_get_content("my-file.txt");

       $pid = $ssh->disown_master
	   Under normal	operation Net::OpenSSH controls	the life-time of the
	   master "ssh"	process	and when the object is destroyed the master
	   process and any connection running over it are terminated.

	   In some (rare) cases, it is desirable to let	the master process and
	   all the running connections survive.	Calling	this method does just
	   that, it tells Net::OpenSSH object that the master process is not
	   its own anymore.

	   The return value is the PID of the master process.

	   Note	also that disowning the	master process does not	affect the
	   operation of	the module in any other	regard.

	   For instance:

	     # See sample/ for a working program
	     my	$ssh = Net::OpenSSH->new($host);
	     my	$sshfs_pid = $ssh->sshfs_import("/home/foo", "my-remote-home");
	     $ssh->stop; # tells the master to stop accepting requests

   Shell quoting
       By default, when	invoking remote	commands, this module tries to mimic
       perl "system" builtin in	regard to argument processing. Quoting
       "system"	in perlfunc:

	 Argument processing varies depending on the number of arguments.  If
	 there is more than one	argument in LIST, or if	LIST is	an array with
	 more than one value, starts the program given by the first element
	 of the	list with arguments given by the rest of the list.  If there
	 is only one scalar argument, the argument is checked for shell
	 metacharacters, and if	there are any, the entire argument is passed
	 to the	system's command shell for parsing (this is "/bin/sh -c" on
	 Unix platforms, but varies on other platforms).

       Take for	example	Net::OpenSSH "system" method:

	 $ssh->system("ls -l *");
	 $ssh->system('ls', '-l', '/');

       The first call passes the argument unchanged to ssh and it is executed
       in the remote side through the shell which interprets metacharacters.

       The second call escapes any shell metacharacters	so that, effectively,
       it is equivalent	to calling the command directly	and not	through	the

       Under the hood, as the Secure Shell protocol does not provide for this
       mode of operation and always spawns a new shell where it	runs the given
       command,	Net::OpenSSH quotes any	shell metacharacters in	the command

       All the methods that invoke a remote command (system, open_ex, etc.)
       accept the option "quote_args" that allows one to force/disable shell

       For instance:

	 $ssh->system({quote_args => 1}, "/path	with spaces/bin/foo");

       will correctly handle the spaces	in the program path.

       The shell quoting mechanism implements some extensions (for instance,
       performing redirections to /dev/null on the remote side)	that can be
       disabled	with the option	"quote_args_extended":

	 $ssh->system({	stderr_discard => 1,
			quote_args => 1, quote_args_extended =>	0 },

       The option "quote_args" can also	be used	to disable quoting when	more
       than one	argument is passed. For	instance, to get some pattern expanded
       by the remote shell:

	 $ssh->system({quote_args => 0}, 'ls', '-l', "/tmp/files_*.dat");

       The method "shell_quote"	can be used to selectively quote some
       arguments and leave others untouched:

	 $ssh->system({quote_args => 0},
		      $ssh->shell_quote('ls', '-l'),

       When the	glob option is set in "scp" and	"rsync"	file transfer methods,
       an alternative quoting method which knows about file wildcards and
       passes them unquoted is used. The set of	wildcards recognized currently
       is the one supported by bash(1).

       Another way to selectively use quote globing or fully disable quoting
       for some	specific arguments is to pass them as scalar references	or
       double scalar references	respectively. In practice, that	means
       prepending them with one	or two backslashes. For	instance:

	 # quote the last argument for globing:
	 $ssh->system('ls', '-l', \'/tmp/my files/filed_*dat');

	 # append a redirection	to the remote command
	 $ssh->system('ls', '-lR', \\'>/tmp/ls-lR.txt');

	 # expand remote shell variables and glob in the same command:
	 $ssh->system('tar', 'czf', \\'$HOME/out.tgz', \'/var/log/server.*.log');

       As shell	quoting	is a tricky matter, I expect bugs to appear in this
       area. You can see how "ssh" is called, and the quoting used setting the
       following debug flag:

	 $Net::OpenSSH::debug |= 16;

       By default, the module assumes the remote shell is some variant of a
       POSIX or	Bourne shell ("bash", "dash", "ksh", etc.). If this is not the
       case, the construction option "remote_shell" can	be used	to select an
       alternative quoting mechanism.

       For instance:

	 $ssh =	Net::OpenSSH->new($host, remote_shell => 'csh');
	 $ssh->system(echo => "hard\n to\n  quote\n   argument!");

       Currently there are quoters available for POSIX (Bourne)	compatible
       shells, "csh" and the two Windows variants "MSWin" (for servers using
       Win32::CreateProcess, see Net::OpenSSH::ShellQuoter::MSWin) and "MSCmd"
       (for servers using "cmd.exe", see Net::OpenSSH::ShellQuoter::MSCmd).

       In any case, you	can always do the quoting yourself and pass the	quoted
       remote command as a single string:

	 # for VMS
	 $ssh->system('DIR/SIZE	NFOO::USERS:[JSMITH.DOCS]*.TXT;0');

       Note that the current quoting mechanism does not	handle possible
       aliases defined by the remote shell. In that case, to force execution
       of the command instead of the alias, the	full path to the command must
       be used.

       In order	to stop	remote processes when they timeout, the	ideal approach
       would be	to send	them signals through the SSH connection	as specified
       by the protocol standard.

       Unfortunately OpenSSH does not implement	that feature so	Net::OpenSSH
       has to use other	imperfect approaches:

       o   close slave I/O streams

	   Closing the STDIN and STDOUT	streams	of the unresponsive remote
	   process will	effectively deliver a SIGPIPE when it tries to access
	   any of them.

	   Remote processes may	not access STDIN or STDOUT and even then,
	   Net::OpenSSH	can only close these channels when it is capturing
	   them, so this approach does not always work.

       o   killing the local SSH slave process

	   This	action may leave the remote process running, creating a	remote
	   orphan so Net::OpenSSH does not use it unless the construction
	   option "kill_ssh_on_timeout"	is set.

       Luckily,	future versions	of OpenSSH will	support	signaling remote
       processes via the mux channel.

   Variable expansion
       The variable expansion feature allows one to define variables that are
       expanded	automatically inside command arguments and file	paths.

       This feature is disabled	by default. It is intended to be used with
       Net::OpenSSH::Parallel and other	similar	modules.

       Variables are delimited by a pair of percent signs ("%"), for instance
       "%HOST%". Also, two consecutive percent signs are replaced by a single

       The special variables "HOST", "USER" and	"PORT" are maintained
       internally by the module	and take the obvious values.

       Variable	expansion is performed before shell quoting (see "Shell

       Some usage example:

	 my $ssh = Net::OpenSSH->new('', expand_vars => 1);
	 $ssh->set_var(ID => 42);
	 $ssh->system("ls >/tmp/ls.out-%HOST%-%ID%");

       will redirect the output	of the "ls" command to
       "/tmp/" on the remote host.

       Besides running commands	on the remote host, Net::OpenSSH also allows
       one to tunnel TCP connections to	remote machines	reachable from the SSH

       That feature is made available through the "tunnel" option of the
       "open_ex" method, and also through wrapper methods "open_tunnel"	and
       "capture_tunnel"	and most others	where it makes sense.


	 $ssh->system({tunnel => 1,
		       stdin_data => "GET / HTTP/1.0\r\n\r\n",
		       stdout_file => "/tmp/$server.res"},
		      $server, 80)
	     or	die "unable to retrieve	page: "	. $ssh->error;

       or capturing the	output of several requests in parallel:

	 my @pids;
	 for (@servers)	{
	   my $pid = $ssh->spawn({tunnel => 1,
				  stdin_file =>	"/tmp/request.req",
				  stdout_file => "/tmp/$_.res"},
				 $_, 80);
	   if ($pid) {
	     push @pids, $pid;
	   else	{
	     warn "unable to spawn tunnel process to $_: " . $ssh->error;
	 waitpid ($_, 0) for (@pids);

       Under the hood, in order	to create a tunnel, a new "ssh"	process	is
       spawned with the	option "-W${address}:${port}" (available from OpenSSH
       5.4 and upwards)	making it redirect its stdio streams to	the remote
       given address. Unlike when "ssh"	"-L" options is	used to	create
       tunnels,	no TCP port is opened on the local machine at any time so this
       is a perfectly secure operation.

       The PID of the new process is returned by the named methods. It must be
       reaped once the pipe or socket handlers for the local side of the
       tunnel have been	closed.

       OpenSSH 5.4 or later is required	for the	tunnels	functionality to work.
       Also, note that tunnel forwarding may be	administratively forbidden at
       the server side (see sshd(8) and	sshd_config(5) or the documentation
       provided	by your	SSH server vendor).

       When connecting to hosts	running	a recent version of OpenSSH sshd, it
       is also possible	to open	connections targeting Unix sockets.

       For instance:

	 my $response =	$ssh->capture({tunnel => 1, stdin_data => $request },

       Currently, this feature requires	a patched OpenSSH ssh client. The
       patch is	available as

   Data	encoding
       Net::OpenSSH has	some support for transparently converting the data
       send or received	from the remote	server to Perl internal	unicode

       The methods supporting that feature are those that move data from/to
       Perl data structures (e.g. "capture", "capture2", "capture_tunnel" and
       methods supporting the "stdin_data" option). Data accessed through
       pipes, sockets or redirections is not affected by the encoding options.

       It is also possible to set the encoding of the command and arguments
       passed to the remote server on the command line.

       By default, if no encoding option is given on the constructor or	on the
       method calls, Net::OpenSSH will not perform any encoding
       transformation, effectively processing the data as "latin1".

       When data can not be converted between the Perl internal	representation
       and the selected	encoding inside	some Net::OpenSSH method, it will fail
       with an "OSSH_ENCODING_ERROR" error.

       The supported encoding options are as follows:

       stream_encoding => $encoding
	   sets	the encoding of	the data send and received on capture methods.

       argument_encoding => $encoding
	   sets	the encoding of	the command line arguments

       encoding	=> $encoding
	   sets	both "argument_encoding" and "stream_encoding".

       The constructor also accepts "default_encoding",
       "default_stream_encoding" and "default_argument_encoding" that set the

   Diverting "new"
       When a code ref is installed at $Net::OpenSSH::FACTORY, calls to	new
       will be diverted	through	it.

       That feature can	be used	to transparently implement connection caching,
       for instance:

	 my $old_factory = $Net::OpenSSH::FACTORY;
	 my %cache;

	 sub factory {
	   my ($class, %opts) =	@_;
	   my $signature = join("\0", $class, map { $_ => $opts{$_} }, sort keys %opts);
	   my $old = $cache{signature};
	   return $old if ($old	and $old->error	!= OSSH_MASTER_FAILED);
	   local $Net::OpenSSH::FACTORY	= $old_factory;
	   $cache{$signature} =	$class->new(%opts);

	 $Net::OpenSSH::FACTORY	= \&factory;

       ... and I am sure it can	be abused in several other ways!

       Sometimes you would like	to use Expect to control some program running
       in the remote host. You can do it as follows:

	 my ($pty, $pid) = $ssh->open2pty(@cmd)
	     or	die "unable to run remote command @cmd";
	 my $expect = Expect->init($pty);

       Then, you will be able to use the new Expect object in $expect as

       This example is adapted from Net::Telnet	documentation:

	 my ($pty, $pid) = $ssh->open2pty({stderr_to_stdout => 1})
	   or die "unable to start remote shell: " . $ssh->error;
	 my $telnet = Net::Telnet->new(-fhopen => $pty,
				       -prompt => '/.*\$ $/',
				       -telnetmode => 0,
				       -cmd_remove_mode	=> 1,
				       -output_record_separator	=> "\r");

	 $telnet->waitfor(-match => $telnet->prompt,
			  -errmode => "return")
	   or die "login failed: " . $telnet->lastline;

	 my @lines = $telnet->cmd("who");


	 waitpid($pid, 0);

   mod_perl and	mod_perl2
       mod_perl	and mod_perl2 tie STDIN	and STDOUT to objects that are not
       backed up by real file descriptors at the operating system level.
       Net::OpenSSH will fail if any of	these handles is used explicitly or
       implicitly when calling some remote command.

       The work-around is to redirect them to "/dev/null" or to	some file:

	 open my $def_in, '<', '/dev/null' or die "unable to open /dev/null";
	 my $ssh = Net::OpenSSH->new($host,
				     default_stdin_fh => $def_in);

	 my $out = $ssh->capture($cmd1);
	 $ssh->system({stdout_discard => 1}, $cmd2);
	 $ssh->system({stdout_to_file => '/tmp/output'}, $cmd3);

       Also, note that from a security stand point, running "ssh" from inside
       the web server process is not a great idea. An attacker exploiting some
       Apache bug would	be able	to access the SSH keys and passwords and gain
       unlimited access	to the remote systems.

       If you can, use a queue (as TheSchwartz)	or any other mechanism to
       execute the ssh commands	from another process running under a different
       user account.

       At a minimum, ensure that "~www-data/.ssh" (or similar) is not
       accessible through the web server!

       See method "sftp".

       See method "any".

       See method "object_remote".

   AnyEvent (and similar frameworks)
       Net::OpenSSH provides all the functionality required to be integrated
       inside event oriented programming framework such	as AnyEvent or
       IO::Async in the	following way:

       1. Create a disconnected	Net::OpenSSH object:
	       my $ssh = Net::OpenSSH->new($host, async	=> 1, ...);

       2. Let the object connect to the	remote host:
	   Use a timer to call the "wait_for_master" method in async mode
	   repeatedly until it returns a true value indicating success.

	   Also, the object error state	needs to be checked after every	call
	   in order to detect failed connections. For instance:

	     my	$ssh = Net::OpenSSH->new(..., async => 1);
	     my	$w;
	     $w	= AE::timer 0.1, 0.1, sub {
	       if ($ssh->wait_for_master(1)) {
		 # the connection has been established!
		 # remote commands can be run now
		 undef $w;
	       elsif ($ssh->error) {
		 # connection can not be established
		 undef $w;

       3. Use the event	framework to launch the	remote processes:
	   Call	Net::OpenSSH "make_remote_command" to construct	commands which
	   can be run using the	framework regular facilities for launching
	   external commands.

	   Error checking should also be performed at this point because the
	   SSH connection could	be broken.

	   For instance:

	     if	(defined(my $cmd = $ssh->make_remote_command(echo => 'hello!'))	{
	       AnyEvent::Util::run_cmd($cmd, %run_cmd_opts);
	     else {
	       # something went	wrong!

	   Alternatively, any of the "open*" methods provided by Net::OpenSSH
	   could also be used to launch	remote commands.

       4. When finished, disconnect asynchronously
	   After initiating an asynchronous disconnect with disconnect(1),
	   repeatedly call "wait_for_master" until you get a defined but false


	     my	$w; $w = AE::timer 0.1,	0.1, sub {
	       my $res = $ssh->wait_for_master(1);

	       if (defined $res	&& !$res) {
		 undef $w;
		 undef $ssh;

	   Be careful not to let the $ssh object go out	of scope until the
	   disconnection has finished, otherwise its destructor	will wait and
	   block your program until the	disconnection has completed.

   Other modules
       CPAN contains several modules that rely on SSH to perform their duties
       as for example IPC::PerlSSH or GRID::Machine.

       Often, it is possible to	instruct them to go through a Net::OpenSSH
       multiplexed connection employing	some available constructor option. For

	 use Net::OpenSSH;
	 use IPC::PerlIPC;
	 my $ssh = Net::OpenSSH->new(...);
	 $ssh->error and die "unable to	connect	to remote host:	" . $ssh->error;
	 my @cmd = $ssh->make_remote_command('/usr/bin/perl');
	 my $ipc = IPC::PerlSSH->new(Command =>	\@cmd);
	 my @r = $ipc->eval('...');


	 use GRID::Machine;
	 my @cmd = $ssh->make_remote_command('/usr/bin/perl');
	 my $grid = GRID::Machine->new(command => \@cmd);
	 my $r = $grid->eval('print "hello world!\n"');

       In other	cases, some kind of plugin mechanism is	provided by the	3rd
       party modules to	allow for different transports.	The method "open2" may
       be used to create a pair	of pipes for transport in these	cases.

       Usually,	Net::OpenSSH works out of the box, but when it fails, some
       users have a hard time finding the cause	of the problem.	This mini
       troubleshooting guide should help you to	find and solve it.

       1 - check the error message
	   Add in your script, after the Net::OpenSSH constructor call,	an
	   error check:

	     $ssh = Net::OpenSSH->new(...);
	     $ssh->error and die "SSH connection failed: " . $ssh->error;

	   The error message will tell what has	gone wrong.

       2 - OpenSSH version
	   Ensure that you have	a version of "ssh" recent enough:

	     $ ssh -V
	     OpenSSH_5.1p1 Debian-5, OpenSSL 0.9.8g 19 Oct 2007

	   OpenSSH version 4.1 was the first to	support	the multiplexing
	   feature and is the minimal required by the module to	work. I	advise
	   you to use the latest OpenSSH (currently 5.8) or at least a more
	   recent version.

	   The "ssh_cmd" constructor option lets you select the	"ssh" binary
	   to use. For instance:

	     $ssh = Net::OpenSSH->new($host,
				      ssh_cmd => "/opt/OpenSSH/5.8/bin/ssh")

	   Some	hardware vendors (e.g. Sun, err... Oracle) include custom
	   versions of OpenSSH bundled with the	operating system. In
	   principle, Net::OpenSSH should work with these SSH clients as long
	   as they are derived from some version of OpenSSH recent enough.
	   Anyway, my advise is	to use the real	OpenSSH	software if you	can!

       3 - run ssh from	the command line
	   Check you can connect to the	remote host using the same parameters
	   you are passing to Net::OpenSSH. In particular, ensure that you are
	   running "ssh" as the	same local user.

	   If you are running your script from a web server, the user would
	   probably be "www", "apache" or something alike.

	   Common problems are:

	   o   Remote host public key not present in known_hosts file.

	       The SSH protocol	uses public keys to identify the remote	hosts
	       so that they can	not be supplanted by some malicious third

	       For OpenSSH, usually the	server public key is stored in
	       "/etc/ssh/" or in
	       "/etc/ssh/" and that	key should be copied
	       into the	"~/.ssh/known_hosts" file in the local machine (other
	       SSH implementations may use other file locations).

	       Maintaining the server keys when	several	hosts and clients are
	       involved	may be somewhat	inconvenient, so most SSH clients, by
	       default,	when a new connection is established to	a host whose
	       key is not in the "known_hosts" file, show the key and ask the
	       user if he wants	the key	copied there.

	   o   Wrong remote host public	key in known_hosts file.

	       This is another common problem that happens when	some server is
	       replaced	or reinstalled from scratch and	its public key changes
	       becoming	different to that installed on the "known_hosts" file.

	       The easiest way to solve	that problem is	to remove the old key
	       from the	"known_hosts" file by hand using any editor and	then
	       to connect to the server	replying "yes" when asked to save the
	       new key.

	   o   Wrong permissions for the "~/.ssh" directory or its contents.

	       OpenSSH client performs several checks on the access
	       permissions of the "~/.ssh" directory and its contents and
	       refuses to use them when	misconfigured. See the FILES section
	       from the	ssh(1) man page.

	   o   Incorrect settings for password or public key authentication.

	       Check that you are using	the right password or that the user
	       public key is correctly installed on the	server.

       4 - security checks on the multiplexing socket
	   Net::OpenSSH	performs some security checks on the directory where
	   the multiplexing socket is going to be placed to ensure that	it can
	   not be accessed by other users.

	   The default location	for the	multiplexing socket is under
	   "~/.libnet-openssh-perl". It	can be changed using the "ctl_dir" and
	   "ctl_path" constructor arguments.

	   The requirements for	that directory and all its parents are:

	   o   They have to be owned by	the user executing the script or by

	   o   Their permission	masks must be 0755 or more restrictive,	so
	       nobody else has permissions to perform write operations on

	   The constructor option "strict_mode"	disables these security
	   checks, but you should not use it unless you	understand its

       5 - file	system must support sockets
	   Some	file systems (as for instance FAT or AFS) do not support
	   placing sockets inside them.

	   Ensure that the "ctl_dir" path does not lay into one	of those file

       Debugging of Net::OpenSSH internals is controlled through the variable
       $Net::OpenSSH::debug. Every bit of this variable	activates debugging of
       some subsystem as follows:

       bit 1 - errors
	   Dumps changes on the	internal object	attribute where	errors are

       bit 2 - ctl_path
	   Dumps information about ctl_path calculation	and the	tests
	   performed on	that directory in order	to decide if it	is secure to
	   place the multiplexing socket inside.

       bit 4 - connecting
	   Dumps information about the establishment of	new master

       bit 8 - commands	and arguments
	   Dumps the command and arguments for every system/exec call.

       bit 16 -	command	execution
	   Dumps information about the progress	of command execution.

       bit 32 -	destruction
	   Dumps information about the destruction of Net::OpenSSH objects and
	   the termination of the SSH master processes.

       bit 64 -	IO loop
	   Dumps information about the progress	of the IO loop on capture

       bit 128 - IO hexdumps
	   Generates hexdumps of the information that travels through the SSH
	   streams inside capture operations.

       bit 512 - OS tracing of the master process
	   Use the module Net::OpenSSH::OSTracer to trace the SSH master
	   process at the OS level.

       For instance, in	order to activate all the debugging flags, you can

	 $Net::OpenSSH::debug =	~0;

       Note that the meaning of	the flags and the information generated	is
       only intended for debugging of the module and may change	without	notice
       between releases.

       If you are using	password authentication, enabling debugging for
       IO::Tty may also	show interesting information:

	   IO::Tty::DEBUG = 1;

       Finally,	by default debugging output is sent to "STDERR". You can
       override	it pointing $Net::OpenSSH::debug_fh to a different file
       handle. For instance:

	   open	my $out, '>', '/tmp/debug.txt' or warn $!;
	   $Net::OpenSSH::debug_fh = $out;
	   $Net::OpenSSH::debug	= -1;

       Q: Is this module secure?

       A: Well,	it tries to be!

       From a security standpoint the aim of this module is to be as secure as
       OpenSSH,	your operating system, your shell and in general your
       environment allow it to be.

       It does not take	any shortcut just to make your life easier if that
       means lowering the security level (for instance,	disabling
       "StrictHostKeyChecking" by default).

       In code supporting features that	are not	just proxied to	OpenSSH, the
       module tries to keep the	same standards of security as OpenSSH (for
       instance, checking directory and	file permissions when placing the
       multiplexing socket).

       On the other hand, and keeping with OpenSSH philosophy, the module lets
       you disable most	(all?) of those	security measures. But just because it
       lets you	do it it doesn't mean it is a good idea	to do so!!!

       If you are a novice programmer or SSH user, and googling	you have just
       found some flag that you	don't understand but that seems	to magically
       solve your connection problems... well, believe me, it is probably a
       bad idea	to use it. Ask somebody	how really knows first!

       Just to make thinks clear, if your code contains	any of the keywords
       from the	(non-exclusive)	list below and you don't know why, you are
       probably	wrecking the security of the SSH protocol:


       Other considerations related to security	you may	like to	know are as

       Taint mode
	   The module supports working in taint	mode.

	   If you are in an exposed environment, you should probably enable it
	   for your script in order to catch any unchecked command for being
	   executed in the remote side.

       Web environments
	   It is a bad idea to establish SSH connections from your webserver
	   because if it becomes compromised in	any way, the attacker would be
	   able	to use the credentials from your script	to connect to the
	   remote host and do anything he wishes there.

       Command quoting
	   The module can quote	commands and arguments for you in a flexible
	   and powerful	way.

	   This	is a feature you should	use as it reduces the possibility of
	   some	attacker being able to inject and run arbitrary	commands on
	   the remote machine (and even	for scripts that are not exposed it is
	   always advisable to enable argument quoting).

	   Having said that, take into consideration that argument-quoting is
	   just	a hack to emulate the invoke-without-a-shell feature of	Perl
	   builtins such as "system" and alike.	There may be bugs(*) on	the
	   quoting code, your particular shell may have	different quoting
	   rules with unhandled	corner cases or	whatever. If your script is
	   exposed to the outside, you should check your inputs	and restrict
	   what	you accept as valid.

	   [* even if this is one of the parts of the module more intensively

	   (see	Shellshock

	   When	executing local	commands, the module always avoids calling the
	   shell so in this way	it is not affected by Shellshock.

	   Unfortunately, some commands	("scp",	"rsync"	and "ssh" when the
	   "ProxyCommand" option is used) invoke other commands	under the hood
	   using the user shell. That opens the	door to	local Shellshock

	   On the remote side invocation of the	shell is unavoidable due to
	   the protocol	design.

	   By default, SSH does	not forward environment	variables but some
	   Linux distributions explicitly change the default OpenSSH
	   configuration to enable forwarding and acceptance of	some specific
	   ones	(for instance "LANG" and "LC_*"	on Debian and derivatives,
	   Fedora does alike) and this also opens the door to Shellshock

	   Note	that the shell used to invoke commands is not "/bin/sh"	but
	   the user shell as configured	in "/etc/passwd", PAM or whatever
	   authentication subsystem is used by the local or remote operating
	   system. Debian users, don't think you are not affected because your
	   "/bin/sh" points to "dash"!

       Frequent	questions about	the module:

       Connecting to switches, routers,	etc.
	   Q: I	can not	get the	method "system", "capture", etc., to work when
	   connecting to some router, switch, etc. What	I am doing wrong?

	   A: Roughly, the SSH protocol	allows for two modes of	operation:
	   command mode	and interactive	mode.

	   Command mode	is designed to run single commands on the remote host.
	   It opens a SSH channel between both hosts, asks the remote computer
	   to run some given command and when it finishes, the channel is
	   closed. It is what you get, for instance, when you run something

	     $ ssh cat foo.txt

	   ... and it is also the way Net::OpenSSH runs	commands on the	remote

	   Interactive mode launches a shell on	the remote hosts with its
	   stdio streams redirected to the local ones so that the user can
	   transparently interact with it.

	   Some	devices	(as probably the one you are using) do not run an
	   standard, general purpose shell (e.g. "bash", "csh" or "ksh") but
	   some	custom program specially targeted and limited to the task of
	   configuring the device.

	   Usually, the	SSH server running on these devices does not support
	   command mode. It unconditionally attaches the restricted shell to
	   any incoming	SSH connection and waits for the user to enter
	   commands through the	redirected stdin stream.

	   The only way	to work-around this limitation is to make your script
	   talk	to the restricted shell	(1-open	a new SSH session, 2-wait for
	   the shell prompt, 3-send a command, 4-read the output until you get
	   to the shell	prompt again, repeat from 3). The best tool for	this
	   task	is probably Expect, used alone or combined with	Net::OpenSSH
	   (see	"Expect").

	   There are some devices that support command mode but	that only
	   accept one command per connection. In that cases, using Expect is
	   also	probably the best option.

	   Nowadays, there is a	new player, Net::CLI::Interaction that may be
	   more	suitable than Expect.

       Connection fails
	   Q: I	am unable to make the module connect to	the remote host...

	   A: Have you read the	troubleshooting	section? (see

       Disable StrictHostKeyChecking
	   Q: Why is "ssh" not run with	"StrictHostKeyChecking=no"?

	   A: Using "StrictHostKeyChecking=no" relaxes the default security
	   level of SSH	and it will be relatively easy to end with a
	   misconfigured SSH (for instance, when "known_hosts" is unwritable)
	   that	could be forged	to connect to a	bad host in order to perform
	   man-in-the-middle attacks, etc.

	   I advice you	to do not use that option unless you fully understand
	   its implications from a security point of view.

	   If you want to use it anyway, past it to the	constructor:

	     $ssh = Net::OpenSSH->new($host,
		      master_opts => [-o => "StrictHostKeyChecking=no"],

       child process STDIN/STDOUT/STDERR is not	a real system file handle
	   Q: Calls to "system", "capture", etc. fail with the previous	error,
	   what's happening?

	   A: The reported stdio stream	is closed or is	not attached to	a real
	   file	handle (e.g. it	is a tied handle). Redirect it to "/dev/null"
	   or to a real	file:

	     my	$out = $ssh->capture({stdin_discard => 1, stderr_to_stdout => 1},

	   See also the	mod_perl entry above.

       Solaris (and AIX	and probably others)
	   Q: I	was trying Net::OpenSSH	on Solaris and seem to be running into
	   an issue...

	   A: The SSH client bundled with Solaris is an	early fork of OpenSSH
	   that	does not provide the multiplexing functionality	required by
	   Net::OpenSSH. You will have to install the OpenSSH client.

	   Precompiled packages	are available from Sun Freeware
	   (<>). There, select your OS version an
	   CPU architecture, download the OpenSSH package and its dependencies
	   and install them. Note that you do not need to configure Solaris to
	   use the OpenSSH server "sshd".

	   Ensure that OpenSSH client is in your path before the system	"ssh"
	   or alternatively, you can hardcode the full path into your scripts
	   as follows:

	     $ssh = Net::OpenSSH->new($host,
				      ssh_cmd => '/usr/local/bin/ssh');

	   AIX and probably some other unixen, also bundle SSH clients lacking
	   the multiplexing functionality and require installation of the real

       Can not change working directory
	   Q: I	want to	run some command inside	a given	remote directory but I
	   am unable to	change the working directory. For instance:

	     $ssh->system('cd /home/foo/bin');

	   does	not list the contents of "/home/foo/bin".

	   What	am I doing wrong?

	   A: Net::OpenSSH (and, for that matter, all the SSH modules
	   available from CPAN but Net::SSH::Expect) run every command in a
	   new session so most shell builtins that are run for its side
	   effects become useless (e.g.	"cd", "export",	"ulimit", "umask",
	   etc., usually, you can list them running "help" from	the shell).

	   A work around is to combine several commands	in one,	for instance:

	     $ssh->system('cd /home/foo/bin && ls');

	   Note	the use	of the shell "&&" operator instead of ";" in order to
	   abort the command as	soon as	any of the subcommands fail.

	   Also, several commands can be combined into one while still using
	   the multi-argument quoting feature as follows:

	     $ssh->system(@cmd1, \\'&&', @cmd2,	\\'&&',	@cmd3, ...);

       Running detached	remote processes
	   Q: I	need to	be able	to ssh into several machines from my script,
	   launch a process to run in the background there, and	then return
	   immediately while the remote	programs keep running...

	   A: If the remote systems run	some Unix/Linux	variant, the right
	   approach is to use nohup(1) that will disconnect the	remote process
	   from	the stdio streams and to ask the shell to run the command on
	   the background. For instance:

	     $ssh->system("nohup $long_running_command &");

	   Also, it may	be possible to demonize	the remote program. If it is
	   written in Perl you can use App::Daemon for that (actually, there
	   are several CPAN modules that provided that kind of functionality).

	   In any case,	note that you should not use "spawn" for that.

       MaxSessions server limit	reached
	   Q: I	created	an $ssh	object and then	fork a lot children processes
	   which use this object. When the children number is bigger than
	   "MaxSessions" as defined in sshd configuration (defaults to 10),
	   trying to fork new remote commands will prompt the user for the

	   A: When the slave SSH client	gets a response	from the remote
	   servers saying that the maximum number of sessions for the current
	   connection has been reached,	it fall	backs to open a	new direct
	   connection without going through the	multiplexing socket.

	   To stop that	for happening, the following hack can be used:

	     $ssh = Net::OpenSSH->new(host,
		 default_ssh_opts => ['-oConnectionAttempts=0'],

       Running remote commands with sudo
	   Q: How can I	run remote commands using "sudo" to become root	first?

	   A: The simplest way is to tell "sudo" to read the password from
	   stdin with the "-S" flag and	to do not use cached credentials with
	   the "-k" flag. You may also like to use the "-p" flag to tell
	   "sudo" to print an empty prompt. For	instance:

	     my	@out = $ssh->capture({ stdin_data => "$sudo_passwd\n" },
				     'sudo', '-Sk',
				     '-p', '',

	   If the version of sudo installed on the remote host does not
	   support the "-S" flag (it tells sudo	to read	the password from its
	   STDIN stream), you can do it	as follows:

	     my	@out = $ssh->capture({ tty => 1,
				       stdin_data => "$sudo_passwd\n" },
				     'sudo', '-k',
				     '-p', '',

	   This	may generate an	spurious and harmless warning from the SSH
	   master connection (because we are requesting	allocation of a	tty on
	   the remote side and locally we are attaching	it to a	regular	pair
	   of pipes).

	   If for whatever reason the methods described	above fail, you	can
	   always revert to using Expect to talk to the	remote "sudo". See the
	   "sample/" script from this module distribution.

       OpenSSH client documentation ssh(1), ssh_config(5), the project web
       <>	and its	FAQ
       <>. scp(1) and rsync(1). The
       OpenSSH Wikibook	<>.

       Net::OpenSSH::Gateway for detailed instruction about how	to get this
       module to connect to hosts through proxies and other SSH	gateway

       Core perl documentation perlipc,	"open" in perlfunc, "waitpid" in

       IO::Pty to known	how to use the pseudo tty objects returned by several
       methods on this package.

       Net::SFTP::Foreign provides a compatible	SFTP implementation.

       Expect can be used to interact with commands run	through	this module on
       the remote machine (see also the	"" and	<> scripts
       in the sample directory).

       SSH::OpenSSH::Parallel is an advanced scheduler that allows one to run
       commands	in remote hosts	in parallel. It	is obviously based on

       SSH::Batch allows one to	run remote commands in parallel	in a cluster.
       It is build on top on "Net::OpenSSH" also.

       Other Perl SSH clients: Net::SSH::Perl, Net::SSH2, Net::SSH,
       Net::SSH::Expect, Net::SCP, Net::SSH::Mechanize.

       Net::OpenSSH::Compat is a package offering a set	of compatibility
       layers for other	SSH modules on top of Net::OpenSSH.

       IPC::PerlSSH, GRID::Machine allow execution of Perl code	in remote
       machines	through	SSH.

       SSH::RPC	implements an RPC mechanism on top of SSH using	Net::OpenSSH
       to handle the connections.

       Net::CLI::Interact allows one to	interact with remote shells and	other
       services. It is specially suited	for interaction	with network
       equipment. The passphrase approach it uses is very clever. You may also
       like to check the other modules <>
       from its	author,	Oliver Gorwits.

   Experimental	features
       Object::Remote integration is highly experimental.

       Support for tunnels targeting Unix sockets is highly experimental.

       Support for the setpgrp feature is highly experimental.

       Support for the gateway feature is highly experimental and mostly

       Support for taint mode is experimental.

   Known issues
       Net::OpenSSH does not work on Windows. OpenSSH multiplexing feature
       requires	passing	file handles through sockets, something	that is	not
       supported by any	version	of Windows.

       It does not work	on VMS either... well, probably, it does not work on
       anything	not resembling a modern	Linux/Unix OS.

       Old versions of OpenSSH "ssh" may leave stdio streams in	non-blocking
       mode. That can result on	failures when writing to "STDOUT" or "STDERR"
       after using the module. In order	to work-around this issue, Perl
       "fcntl" in perlfunc can be used to unset	the non-blocking flag:

	 my $flags = fcntl(STDOUT, F_GETFL, 0);
	 fcntl(STDOUT, F_SETFL,	$flags & ~O_NONBLOCK);

   Reporting bugs and asking for help
       To report bugs send an email to the address that	appear below or	use
       the CPAN	bug tracking system at <>.

       Post questions related to how to	use the	module in PerlMonks
       <>,	you will probably get faster responses than if
       you address me directly and I visit PerlMonks quite often, so I will
       see your	question anyway.

   Commercial support
       Commercial support, professional	services and custom software
       development around this module are available through my current
       company.	Drop me	an email with a	rough description of your requirements
       and we will get back to you ASAP.

   My wishlist
       If you like this	module and you are feeling generous, take a look at my
       Amazon Wish List: <>.

       Also consider contributing to the OpenSSH project this module builds
       upon: <>.

       - Tests for "scp_*", "rsync_*" and "sftp" methods

       - Make "pipe_in"	and "pipe_out" methods "open_ex" based

       - "auto_discard_streams"	feature	for mod_perl2 and similar environments

       - Refactor open_ex support for multiple commands, maybe just keeping
	 tunnel, ssh and raw

       Send your feature requests, ideas or any	feedback, please!

       The source code of this module is hosted	at GitHub:

       Code contributions to the module	are welcome but	you should obey	the
       following rules:

       Only Perl 5.8.4 required
	   Yes,	that's pretty old, but Net::OpenSSH is intended	to be also
	   used	by system administrators that sometimes	have to	struggle with
	   old systems.	The reason to pick 5.8.4 is that it has	been the
	   default perl	on Solaris for a long time.

       Avoid the "All the world's a Linux PC" syndrome
	   The module should work on any (barely) sane Unix or Linux operating
	   system. Specially, it should	not be assumed that the	over-featured
	   GNU utilities and toolchain are available.

       Dependencies are	optional
	   In order to make the	module very easy to install, no	mandatory
	   dependencies	on other CPAN modules are allowed.

	   Optional modules, that are loaded only on demand, are acceptable
	   when	they are used for adding new functionality (as it is done, for
	   instance, with IO::Pty).

	   Glue	code for integration with 3rd party modules is also allowed
	   (as it is done with Expect).

	   Usage of language extension modules and alike is not	acceptable.

       Tests should be lax
	   We don't want false negatives when testing. In case of doubt	tests
	   should succeed.

	   Also, in case of tests invoking some	external program, it should be
	   checked that	the external program is	available and that it works as
	   expected or otherwise skip those tests.

       Backward	compatibility
	   Nowadays Net::OpenSSH is quite stable and there are lots of scripts
	   out there using it that we don't want to break, so, keeping the API
	   backward compatible is a top	priority.

	   Probably only security issues could now justify a backward
	   incompatible	change.

       Follow my coding	style
	   Look	at the rest of the code.

	   I let Emacs do the formatting for me	using cperl-mode PerlStyle.

       Talk to me
	   Before making a large change	or implementing	a new feature get in
	   touch with me.

	   I may have my own ideas about how things should be done. It is
	   better if you know them before hand,	otherwise, you risk getting
	   your	patch rejected.

       Well, actually you should know that I am	quite good at rejecting
       patches but it is not my	fault!

       Most of the patches I get are broken in some way: they don't follow the
       main module principles, sometimes the author didn't get the full
       picture and solved the issue in a short-sighted way, etc.

       In any case, you	should not be discouraged to contribute. Even if your
       patch is	not applied directly, seeing how it solves your	requirements
       or, in the case of bugs,	the underlying problem analysis	may be very
       useful and help me to do	it... my way.

       I always	welcome	documentation corrections and improvements.

       Copyright (C) 2008-2016 by Salvador FandiA+-o (

       This library is free software; you can redistribute it and/or modify it
       under the same terms as Perl itself, either Perl	version	5.10.0 or, at
       your option, any	later version of Perl 5	you may	have available.

perl v5.24.1			  2016-06-10		       Net::OpenSSH(3)


Want to link to this manual page? Use this URL:

home | help