Te cuento mi experiencia con este programa:
Using perl Syntax Highlighting
1 #!/usr/bin/perl
2
3
use Net
::SFTP;
4
use Net
::SFTP::Constants ':status';
5
use strict
;
6
7
my $host = 'aproxi44.aproxi.com';
8
my $user = 'explorer';
9
my $pass = 'esta7i1ococo';
10
11
my $sftp = Net
::SFTP->new($host,
12 debug
=> 1
,
13 user
=> $user ,
14 password
=> $pass ,
15 ssh_args
=> {
16 protocol
=> 2
,
17
},
18
);
19
20
my $fichero = 'msgid.cache';
21
22
$sftp->get($fichero);
23
24
my ($status, $msg) = $sftp->status;
25
26
$status == SSH2_FX_OK
or die "ERROR en el get de $fichero: $msg";Coloreado en 0.002 segundos, usando
GeSHi 1.0.8.4
Bueno, la misión del programa es conectarse a otra y traerse un fichero, por medio del protocolo SSH, y el mecanismo del SFTP. En mi máquina, en mi directorio ~/.ssh/, está configurado que el acceso a esa máquina ha de ser por el puerto 2222. También tengo la clave pública del servidor, por lo que puedo acceder directamente por SSH a esa máquina, sin necesidad de contraseñas, pero en este caso, da igual.
De las primeras líneas, no hay que comentar apenas nada, hasta la 11, donde creamos el objeto de conexión.
Aquí, lo importante, al principio, es activar el modo debug para saber qué es lo que está haciendo el programa. Aparte, le indico que el servidor sólo admitirá el protocolo SSH2.
Esta es la salida:
- Código: Seleccionar todo
explorer@casa:~/Documents/Software/Perl> ./kk.pl
casa: Reading configuration data /home/explorer/.ssh/config
casa: Reading configuration data /etc/ssh_config
casa: Connecting to aproxi44.aproxi.com, port 2222.
casa: Remote version string: SSH-2.0-OpenSSH_3.8.1p1 Debian-8.sarge.6
casa: Remote protocol version 2.0, remote software version OpenSSH_3.8.1p1 Debian-8.sarge.6
casa: Net::SSH::Perl Version 1.30, protocol version 2.0.
casa: No compat match: OpenSSH_3.8.1p1 Debian-8.sarge.6.
casa: Connection established.
casa: Sent key-exchange init (KEXINIT), wait response.
casa: Algorithms, c->s: 3des-cbc hmac-sha1 none
casa: Algorithms, s->c: 3des-cbc hmac-sha1 none
casa: Entering Diffie-Hellman Group 1 key exchange.
casa: Sent DH public key, waiting for reply.
casa: Received host key, type 'ssh-dss'.
casa: Host 'aproxi44.aproxi.com' is known and matches the host key.
casa: Computing shared secret key.
casa: Verifying server signature.
casa: Waiting for NEWKEYS message.
casa: Enabling incoming encryption/MAC/compression.
casa: Send NEWKEYS, enable outgoing encryption/MAC/compression.
casa: Sending request for user-authentication service.
casa: Service accepted: ssh-userauth.
casa: Trying empty user-authentication request.
casa: Authentication methods that can continue: publickey,password,keyboard-interactive.
casa: Next method to try is publickey.
casa: Trying pubkey authentication with key file '/home/explorer/.ssh/id_dsa'
casa: Authentication methods that can continue: publickey,password,keyboard-interactive.
casa: Next method to try is publickey.
casa: Next method to try is password.
casa: Trying password authentication.
casa: Login completed, opening dummy shell channel.
casa: channel 0: new [client-session]
casa: Requesting channel_open for channel 0.
casa: channel 0: open confirm rwindow 0 rmax 32768
casa: channel 1: new [client-session]
casa: Requesting channel_open for channel 1.
casa: Sending subsystem: sftp
casa: Requesting service subsystem on channel 1.
casa: channel 1: open confirm rwindow 0 rmax 32768
casa: sftp: Sending SSH2_FXP_INIT
casa: sftp: Remote version: 3
casa: sftp: Sent message T:17 I:0
casa: sftp: Received stat reply T:105 I:0
casa: sftp: Sent SSH2_FXP_OPEN I:1 P:msgid.cache
casa: sftp: Sent message SSH2_FXP_READ I:2 O:0
casa: sftp: Received reply T:103 I:2
casa: sftp: In read loop, got 8192 offset 0
casa: sftp: Sent message SSH2_FXP_READ I:3 O:8192
casa: channel 1: window 16291 sent adjust 16477
casa: sftp: Received reply T:103 I:3
casa: sftp: In read loop, got 8192 offset 8192
casa: sftp: Sent message SSH2_FXP_READ I:4 O:16384
casa: sftp: Received reply T:103 I:4
casa: sftp: In read loop, got 8192 offset 16384
[ unas cuantas líneas parecidas a estas, y que pueden aprovecharse para hacer una barra de progreso ]
casa: sftp: Sent message SSH2_FXP_READ I:18 O:128052
casa: sftp: Received reply T:101 I:18
casa: sftp: Sent message T:4 I:19
explorer@casa:~/Documents/Software/Perl>
Al principio me asustó la línea que pone 'No compat match: OpenSSH_3.8.1p1 Debian-8.sarge.6', pero sí que funcionó todo lo demás.
Ves que se conecta y se baja un fichero de 128Kb. Si le hubiera pedido que se bajara un fichero inexistente, la salida final sería algo así:
- Código: Seleccionar todo
casa: sftp: Sending SSH2_FXP_INIT
casa: sftp: Remote version: 3
casa: sftp: Sent message T:17 I:0
casa: sftp: Received stat reply T:101 I:0
Couldn't stat remote file: No such file or directory at ./kk.pl line 22
ERROR en el get de msgid.1cache: No such file or directory at ./kk.pl line 26.
Ves que sale un mensaje de error del protocolo SSH y luego sale el mensaje de error de mi línea
die.
El resultado del get lo obtengo con status, en la línea 24. Ahí, status es llamada en contexto lista, y los dos primeros valores que me devuelve los meto en las dos variables declaradas por my(). La primera variable guarda el código del error y la segunda, el mensaje del error. Si la hubiera llamado en contexto escalar solo hubiera devuelto el código de error.
La línea 26 hace la pregunta de si el resultado es igual a SSH2_FX_OK (que realmente vale
0). Si no lo es, el programa muere mostrando el mensaje del error.
Decir que, por estar estos módulos hechos en Perl y no ser librerías compiladas, a veces tardan bastantes segundos en pasar de una fase del login a otro. Por ejemplo, cuando dice 'Computing shared secret key'.
Si lo ejecutamos con
debug => 0, entonces la salida con error, se reduce a:
- Código: Seleccionar todo
explorer@casa:~/Documents/Software/Perl> ./kk.pl
Couldn't stat remote file: No such file or directory at ./kk.pl line 22
ERROR en el get de msgid1.cache: No such file or directory at ./kk.pl line 26.
explorer@casa:~/Documents/Software/Perl>
Lo que no he conseguido es capturar el mensaje de error del módulo, con la ayuda de eval, así que quizás sólo quede la opción de desviar el STDERR para que no salga en pantalla. No es muy importante si en tu programa el usuario no ve la consola o terminal.