Zum Hauptinhalt springen
Viele Menschen haben automatisierte Prozesse für die Übertragung von Dateien per FTP entwickelt. Dafür gibt es verschiedene Möglichkeiten, von denen einige besser sind als andere. In diesem Blog werden die verschiedenen Ansätze erläutert und die jeweiligen Vor- und Nachteile aufgezeigt. Außerdem wird ein Problem behandelt, das zur Übertragung unvollständiger Dateien führen kann.
Der einfachste Ansatz besteht darin, Ihre Benutzer-ID, Ihr Passwort und alle Ihre FTP-Anfragen in ein Befehlsmakro (Abbildung 1) einzufügen und dieses einfach auszuführen (Abbildung 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

Abbildung 1 – ftp1.cm – einfaches Befehlsmakro
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.
Abbildung 2 – ftp1.cm – Ausführung eines einfachen Befehlsmakros
Der Nachteil dieses Ansatzes besteht darin, dass Ihre Benutzer-ID und vor allem Ihr Passwort als Klartext Teil des Makros sind. Jeder, der Zugriff auf das Makro hat, kann diese Informationen einsehen. Der zweite Ansatz besteht darin, die .netrc-Datei zur Speicherung Ihrer Benutzer-ID und Ihres Passworts zu verwenden (Abbildung 3). Das Befehlsmakro (Abbildung 4) enthält dann lediglich die auszuführenden FTP-Anfragen (Abbildung 5).
machine 172.16.1.116
login Noah_Davids
password MYPASSWORD
Abbildung 3 – .netrc-Datei
&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
Abbildung 4 – ftp2.cm – Befehlsmakro ohne Benutzer-ID und Passwort
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.
Abbildung 5 – ftp2.cm – Ausführen des Befehlsmakros ohne Benutzer-ID und Passwort
Die .netrc-Datei funktioniert nur, wenn der Eigentümer der einzige ist, der Zugriff auf die Datei hat (Abbildung 6). Wenn jemand anderes Lesezugriff hat (Abbildung 7), funktioniert sie nicht und es wird eine Passwortabfrage angezeigt (Abbildung 8).
display_access .netrc -all
%phx_vos#m15_mas>SysAdmin>Noah_Davids>.netrc
w  Noah_Davids.*
n  *.*
Abbildung 6 – Korrekte ACLs in der .netrc-Datei
display_access .netrc -all
%phx_vos#m15_mas>SysAdmin>Noah_Davids>.netrc
w  Noah_Davids.*
r  *.CAC
n  *.*
Abbildung 7 – Falsche ACLs in der .netrc-Datei
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.
Abbildung 8 – Passwortabfrage, wenn .netrc falsche ACLs enthält
Sie können alle Befehle in der Datei .netrc platzieren, indem Sie ein FTP-Makro erstellen. Wenn das Makro den Namen „init“ trägt (Abbildung 9), wird es nach der Anmeldung automatisch ausgeführt. Dadurch ist das VOS-Befehlsmakro nur eine Zeile lang (Abbildung 10), nämlich der Befehl ftp. Das größte Problem bei diesem Ansatz ist, dass es keine Fehlerbehebung gibt; Sie können den Status der FTP-Anfragen nicht mit der Funktion (command_status) überprüfen (Abbildung 11).
machine 172.16.1.116
login Noah_Davids
password MYPASSWORD
macdef init
put foo
get bar
quit
Abbildung 9 – .netrc-Datei mit Init-Makro
ftp 172.16.1.116
Abbildung 10 – ftp3.cm – Makro bei Verwendung mit einer .netrc-Datei, die ein init-FTP-Makro enthält
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.
Abbildung 11 – ftp3.cm – Ausgabe bei Verwendung des Makros „init“ – keine Fehlerbehebung
Viele Makros, die ich gesehen habe, warten in einer Schleife darauf, dass eine Datei in einem Verzeichnis erscheint. Sobald dies geschieht, verwendet das Makro FTP, um sie zu übertragen (Abbildung 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
Abbildung 12 – ftp4.cm – Makro wartet auf das Erscheinen einer Datei und überträgt diese dann
Das Problem bei diesem Ansatz ist, dass FTP eine Datei lesen kann, die noch geöffnet ist und in die gerade geschrieben wird. Bei einer großen Datei oder wenn das Timing einfach ungünstig ist, wird nur ein Teil der Datei übertragen (Abbildung 13).
1234567890
abcdefghij
1234567890
abcdefghij
1234567890
abcdefghij
1234567890
abcdefghij
1234567890
abcdefghij
Abbildung 13 – Nur ein Teil der Datei wird übertragen.
1234567890
abcdefghij
1234567890
abcdefghij
1234567890
abcdefghij
1234567890
abcdefghij
1234567890
abcdefghij
this is the last record
Abbildung 14 – vollständige Datei
Es reicht nicht aus, nur zu überprüfen, ob die Datei vorhanden ist, sondern Sie müssen auch überprüfen, ob die Datei gesperrt ist (Abbildung 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
Abbildung 15 – ftp5.cm – Überprüfen, ob eine Datei vor der Übertragung entsperrt ist
Der beste Ansatz ist daher, die .netrc-Datei zur Speicherung Ihrer Benutzer-ID und Ihres Passworts zu verwenden und ein VOS-Befehlsmakro, mit dem Sie nach jeder Anfrage den Befehlsstatus überprüfen können, um die tatsächlichen Anfragen zu steuern. Überprüfen Sie außerdem vor der Übertragung einer Datei, ob diese nicht gesperrt ist.
Einige von Ihnen fragen sich vielleicht, was SFTP ist. Die Automatisierung von Dateiübertragungen mit SFTP ist etwas völlig anderes und wird in meinem nächsten Blogbeitrag behandelt.