Ir al contenido principal
Mucha gente ha creado procesos automatizados para transferir archivos usando FTP. Hay varias maneras diferentes de hacer esto, algunas mejores que otras. Este blog discutirá los diferentes enfoques e identificará las ventajas y desventajas de cada uno. También cubrirá un tema que puede resultar en la transferencia de archivos incompletos.
El enfoque más simple es poner su ID de usuario, contraseña y todas sus solicitudes de FTP en un macro de comando (figura 1) y simplemente ejecutarlo (figura 2).
&attach_input
ftp 172.16.1.116
Noah_Davids
MYPASSWORD
put foo
&if (command_status) ^= 226 &then &goto ERROR1
get bar
&if (command_status) ^= 226 &then &goto ERROR2
quit
&
&label ERROR1
..display_line Could not put file
quit
&return
&
&label ERROR2
..display_line Could not get file
quit
&return

Figura 1 - ftp1.cm - comando simple macro
ftp1
Connected to 172.16.1.116.
220 phx_vos-m16 FTP server (FTP 1.0 for Stratus STCP) ready. (Compatible with OS
+ TCP/IP)
User (172.16.1.116:Noah_Davids): 331 Password required for nd.
Password:
230 User Noah_Davids.CAC logged in.
200 PORT command successful.
150 Opening data connection for foo (172.16.1.34,49253)0.
226 Transfer complete.
80 bytes sent in 0.01 seconds (6.85 Kbytes/sec)
200 PORT command successful.
550 bar: No such file or directory.
recvrequest: Bad file number.
Get transfer did not complete
Could not get file
221 Goodbye.
Figura 2 - ftp1.cm - ejecución de una macro de comando simple
El inconveniente de este enfoque es que su identificación de usuario y más importante aún, su contraseña están en texto claro como parte de la macro. Cualquiera que tenga acceso a la macro puede verla. El segundo enfoque es usar el archivo .netrc para guardar tu ID de usuario y tu contraseña. (figura 3). El comando macro (figura 4) entonces sólo incluye las solicitudes FTP para ejecutar (figura 5).
machine 172.16.1.116
login Noah_Davids
password MYPASSWORD
Figura 3 - Archivo .netrc
&attach_input
ftp 172.16.1.116
put foo
&if (command_status) ^= 226 &then &goto ERROR1
get bar
&if (command_status) ^= 226 &then &goto ERROR2
quit
&
&label ERROR1
..display_line Could not put file
quit
&return
&
&label ERROR2
..display_line Could not get file
quit
&return
Figura 4 - ftp2.cm - comando macro sin ID de usuario y contraseña
ftp2
Connected to 172.16.1.116.
220 phx_vos-m16 FTP server (FTP 1.0 for Stratus STCP) ready. (Compatible with OS
+ TCP/IP)
331 Password required for nd.
230 User Noah_Davids.CAC logged in.
200 PORT command successful.
150 Opening data connection for foo (172.16.1.34,49256)0.
226 Transfer complete.
80 bytes sent in 0.04 seconds (2.09 Kbytes/sec)
200 PORT command successful.
550 bar: No such file or directory.
recvrequest: Bad file number.
Get transfer did not complete
Could not get file
221 Goodbye.
Figura 5 - ftp2.cm - ejecutando comando macro sin ID de usuario y contraseña
El archivo .netrc sólo funciona si el propietario es el único que tiene acceso a él (figura 6). Si alguien más tiene acceso de lectura (figura 7) no funcionará y se mostrará un aviso de contraseña (figura 8).
display_access .netrc -all
%phx_vos#m15_mas>SysAdmin>Noah_Davids>.netrc
w  Noah_Davids.*
n  *.*
Figura 6 - ACLs correctos en el archivo .netrc
display_access .netrc -all
%phx_vos#m15_mas>SysAdmin>Noah_Davids>.netrc
w  Noah_Davids.*
r  *.CAC
n  *.*
Figura 7 - ACLs incorrectos en el archivo .netrc
ftp2
Connected to 172.16.1.116.
220 phx_vos-m16 FTP server (FTP 1.0 for Stratus STCP) ready. (Compatible with OS
+ TCP/IP)
User (172.16.1.116:Noah_Davids): 331 Password required for put foo.
Password:
530 Login incorrect.
Login failed.
221 Goodbye.
Figura 8 - aviso de contraseña cuando .netrc tiene los ACLs incorrectos
Puedes colocar todos los comandos en el archivo .netrc creando una macro FTP. Si la macro se llama "init" (figura 9) se ejecuta automáticamente después del inicio de sesión, esto hace que la macro del comando VOS tenga sólo 1 línea de longitud (figura 10), el comando ftp. El principal problema de este enfoque es que no hay recuperación de errores; no se puede comprobar el estado de ninguna de las solicitudes FTP con la función (command_status) (figura 11).
machine 172.16.1.116
login Noah_Davids
password MYPASSWORD
macdef init
put foo
get bar
quit
Figura 9 - Archivo .netrc con macro de inicio
ftp 172.16.1.116
Figura 10 - ftp3.cm - macro cuando se usa con un archivo .netrc que contiene un macro FTP inicial
ftp3
Connected to 172.16.1.116.
220 phx_vos-m16 FTP server (FTP 1.0 for Stratus STCP) ready. (Compatible with OS
+ TCP/IP)
331 Password required for nd.
230 User Noah_Davids.CAC logged in.
put foo
200 PORT command successful.
150 Opening data connection for foo (172.16.1.34,49276)0.
226 Transfer complete.
80 bytes sent in 0.01 seconds (9.52 Kbytes/sec)
get bar
200 PORT command successful.
550 bar: No such file or directory.
recvrequest: Bad file number.
Get transfer did not complete
quit
221 Goodbye.
Figura 11 - ftp3.cm - salida cuando se usa macro de inicio - no hay recuperación de errores
Muchas macros que he visto sólo hacen un bucle esperando que un archivo aparezca en un directorio, cuando lo hace la macro usa FTP para transferirlo (figura 12).
&attach_input
&label AGAIN
&if (exists new_file) = 1 &then &goto FTP
display_line No new_file as of (time)
sleep -seconds 15
&goto AGAIN
&
&
&label FTP
ftp 172.16.1.116
put new_file
&if (command_status) = 226 &then ..display_line OK
&else &do
..display_line
..display_line ERROR
..display_line
&end
quit
Figura 12 - ftp4.cm - macro esperando que aparezca un archivo y luego transferirlo
El problema con este enfoque es que el FTP puede leer un archivo que aún está abierto y en proceso de escritura. En el caso de un archivo grande o si el momento es malo, el resultado será que sólo se transferirá una parte del archivo (figura 13).
1234567890
abcdefghij
1234567890
abcdefghij
1234567890
abcdefghij
1234567890
abcdefghij
1234567890
abcdefghij
Figura 13 - sólo una parte del archivo es transferida
1234567890
abcdefghij
1234567890
abcdefghij
1234567890
abcdefghij
1234567890
abcdefghij
1234567890
abcdefghij
this is the last record
Figura 14 - archivo completo
No basta con comprobar si el archivo existe, también hay que comprobar si el archivo está bloqueado (figura 15).
&attach_input
&label AGAIN
&if (exists new_file) = 1 & (locked new_file) = 0 &then &goto FTP
display_line new_file not ready for transfer as of (time)
sleep -seconds 15
&goto AGAIN
&
&
&label FTP
ftp 172.16.1.116
put new_file
&if (command_status) = 226 &then ..display_line OK
&else &do
..display_line
..display_line ERROR
..display_line
&end
quit
Figura 15 - ftp5.cm - comprobando que un archivo está desbloqueado antes de transferirlo
Así que el mejor enfoque es usar el archivo .netrc para guardar su ID de usuario y contraseña y un macro de comando VOS con la capacidad de comprobar el estado_de_comando después de cada solicitud para controlar las solicitudes reales. Además, antes de transferir un archivo, compruebe que no esté bloqueado.
Algunos de ustedes se preguntan sobre el SFTP; la automatización de las transferencias de archivos con SFTP es completamente diferente y se discutirá en mi próximo blog.