Transferencia por sftp

El protocolo SFTP no es el resultado de ejecutar FTP sobre SSH. Se trata de un nuevo protocolo para la transferencia segura de ficheros.

Si se establece autentificación no interactiva con una máquina que provee un servicio SFTP es posible usar sftp en modo batch:

pp2@mymachine:~/Lbook$ ssh-copy-id -i ~/.ssh/id_dsa.pub casiano@ftp.someplace.ull.es
25
Now try logging into the machine, with "ssh 'casiano@ftp.someplace.ull.es'", and check in:

  .ssh/authorized_keys

  to make sure we haven't added extra keys that you weren't expecting.

Ahora escribimos un guión para el cliente sftp:

pp2@nereida:~/Lbook$ cat -n instituto.sftp
     1  cd asignas/asignas/PRGPAR2/perlexamples
     2  lcd /home/pp2/public_html/perlexamples/
     3  put *

La opción -b de sftp nos permite hacer la transferencia de forma automática:

pp2@nereida:~/Lbook$ sftp -b instituto.sftp casiano@ftp.instituto.ull.es >/dev/null

Copias Recursivas de Directorios

Si se intenta copiar una carpeta usando comandos como get o mget se obtiene un error:

pp2@europa:~/Lbook$ sftp beowulf
Connecting to beowulf...
sftp> cd /tmp
sftp> put perlexamples/
skipping non-regular file perlexamples/

Sin embargo podemos usar parpush para obtener el directorio:

pp2@europa:/tmp$ ssh beowulf 'ls -ld p*/'
drwxr-xr-x  3 casiano casiano 4096 ago  1  2008 perl5lib/
drwxr-xr-x  2 casiano casiano 4096 may 25 18:38 pi/
drwxr-xr-x 74 casiano casiano 4096 mar 20 13:15 pl/
drwxr-xr-x 67 casiano casiano 4096 abr 21 15:51 pp2/
drwxr-xr-x  6 casiano casiano 4096 mar 12  2008 public_html/
pp2@europa:/tmp$ parpush beowulf:pi/ :/tmp/
pp2@europa:/tmp$ ls -ltrd /tmp/p
pi/                pp2sftp2etsii.log
pp2@europa:/tmp$ tree /tmp/pi
/tmp/pi
|-- Makefile
|-- pi
`-- pi.c

0 directories, 3 files
También es posible usar scp con la opción -r

vim y FTP

Es posible editar ficheros con vim vía FTP :

pp2@europa:/tmp$ vi ftp://ftp.etsii.ull.es/asignas/PRGPAR2/perlexamples/index.html

El Módulo Net::SFTP::Foreign

El módulo Net::SFTP::Foreign provee de una interface para la conexión sftp con una máquina que ofrezca el servicio sftp:

pp2@europa:/tmp$ perl -MNet::SFTP::Foreign -wde 0
main::(-e:1):   0
DB<1> $sftp = Net::SFTP::Foreign->new('beowulf')
DB<2> @f = $sftp->ls('.', wanted => qr{matr})
DB<3> x @f
0  ARRAY(0xce0820)
   0  HASH(0x10a3b90)
      'a' => Net::SFTP::Foreign::Attributes=HASH(0x10a3af0)
         'atime' => 1243268469
         'flags' => 15
         'gid' => 1001
         'mtime' => 1241458791
         'perm' => 16877
         'size' => 4096
         'uid' => 1001
      'filename' => 'matrix_open'
      'longname' => 'drwxr-xr-x    2 casiano  casiano      4096 May  4 18:39 matrix_open'
   1  HASH(0x10a3990)
      'a' => Net::SFTP::Foreign::Attributes=HASH(0x1079ba0)
         'atime' => 1243268472
         'flags' => 15
         'gid' => 1001
         'mtime' => 1241458793
         'perm' => 16877
         'size' => 4096
         'uid' => 1001
      'filename' => 'matrix_open2'
      'longname' => 'drwxr-xr-x    2 casiano  casiano      4096 May  4 18:39 matrix_open2'
DB<4> @f = $sftp->ls('.', wanted => sub { $_[1]->{a}{size} > 112900 })
DB<5> x @f
0  ARRAY(0x10a3ba0)
   0  HASH(0x10ec120)
      'a' => Net::SFTP::Foreign::Attributes=HASH(0x10ec110)
         'atime' => 1171006339
         'flags' => 15
         'gid' => 1001
         'mtime' => 1171006319
         'perm' => 33188
         'size' => 187282
         'uid' => 1001
      'filename' => 'Parse-Eyapp-1.069.tar.gz'
      'longname' => '-rw-r--r--    1 casiano  casiano    187282 Feb  9  2007 Parse-Eyapp-1.069.tar.gz'
   1  HASH(0x10ec190)
      'a' => Net::SFTP::Foreign::Attributes=HASH(0x10ec240)
         'atime' => 1239619337
         'flags' => 15
         'gid' => 1001
         'mtime' => 1237204712
         'perm' => 33152
         'size' => 410479
         'uid' => 1001
      'filename' => '231s_blog.pdf'
      'longname' => '-rw-------    1 casiano  casiano    410479 Mar 16 11:58 231s_blog.pdf'
DB<6> !!mkdir chuchu
DB<7> $sftp->rget('_Inline/', 'chuchu')
DB<8> !! tree chuchu
chuchu
|-- build
|-- config
`-- lib
    `-- auto
        `-- pi_pl_b86b
            |-- pi_pl_b86b.bs
            |-- pi_pl_b86b.inl
            `-- pi_pl_b86b.so

4 directories, 4 files

Una alternativa es el módulo Net::SFTP.

Ejercicios

Ejercicio 2.1.11   Sugiera soluciones a la pregunta:

How to detect failure from batch SFTP and SHELL operations?

encontrada en el foro Shell Programming and Scripting. El texto de la pregunta es como sigue:

I'm doing something like this within a SHELL script (.sh): Code:

                                sftp -b getfile user@host
                                generate_rmfile.sh
                                sftp -b rmfile user@host

The first line executes batched SFTP operations to download files. If it fails, I would want to skip the rest of the lines. How would I be able to do it? Is there some return codes that I could catch and check?

Similarly, my second line calls another SHELL script to generate a file call rmfile. If the file generation fails, I would want to skip the next SFTP batched command, how could I achieve this?

Una de las soluciones comentadas sugiere hacer un pipe de los errores a fichero:

sftp -b getfile user@host | tee sftp_log1
[perform error checking against sftp_log1]
¿Cómo podemos garantizar que STDERR esta siendo redirigido en pipe?. Observe la siguiente secuencia de comandos:
lusasoft@LusaSoft:/tmp$ rm ksocket-root kde-root kde-lusasoft
rm: no se puede borrar «ksocket-root»: Es un directorio
rm: no se puede borrar «kde-root»: Es un directorio
rm: no se puede borrar «kde-lusasoft»: Es un directorio
lusasoft@LusaSoft:/tmp$ rm /usr/local/bin/ /usr/bin /root 2>&1 | sort -
rm: no se puede borrar «/root»: Es un directorio
rm: no se puede borrar «/usr/bin»: Es un directorio
rm: no se puede borrar «/usr/local/bin/»: Es un directorio

Ejercicio 2.1.12   Lea también la pregunta Detecting sftp batch upload errors en el foro comp.security.ssh.

I am trying to write a script that will handle automated file transfers to and from an sftp server, but am having trouble detecting upload errors. What I am trying to do is this:

  sftp -oIdentityFile=id_dsa -b batchfile user@server

...where batch file contains:

  put /my/local/file /my/remote/file
  bye

When the upload is successful, everything is fine. If the upload fails (because the target directory doesn't exist, or if user doesn't have write access to the target directory) sftp does not fail as I would expect. The man page says ...

¿Que ocurre si batchfile contiene varios comandos y falla el primero? ¿Como podemos en tal caso hacer que no se ejecuten los subsiguientes comandos en getfile? ¿Que soluciones se le ocurren?



Subsecciones
Casiano Rodríguez León
Licencia de Creative Commons
Programación Distribuida y Mejora del Rendimiento
por Casiano Rodríguez León is licensed under a Creative Commons Reconocimiento 3.0 Unported License.

Permissions beyond the scope of this license may be available at http://campusvirtual.ull.es/ocw/course/view.php?id=44.
2012-06-19