Domanda

Attualmente sto creando un lavoro notturno che chiama uno script Unix che a sua volta crea e trasferisce un file utilizzando ftp . Vorrei controllare tutti i possibili codici di ritorno. La pagina man per ftp non elenca i codici di ritorno. Qualcuno sa dove trovare un elenco? Qualcuno con esperienza con questo? Abbiamo altri script che richiedono alcune stringhe di ritorno nel registro e inviano un'e-mail in caso di errore. Tuttavia, spesso mancano codici imprevisti. Sto quindi inserendo il motivo nel registro e nell'e-mail.

È stato utile?

Soluzione

Il comando ftp non restituisce altro che zero sulla maggior parte delle implementazioni che ho incontrato.

È molto meglio elaborare i codici a tre cifre nel registro - e se stai inviando un file binario, puoi verificare che i byte inviati siano corretti.

I codici a tre cifre sono chiamati "codici serie" e un elenco può essere trovato qui

Altri suggerimenti

Ho scritto uno script per trasferire solo un file alla volta e in quello script usa grep per controllare il messaggio 226 Transfer complete . Se lo trova, grep restituisce 0.

ftp -niv < "$2"_ftp.tmp | grep "^226 "

Installa il pacchetto ncftp . Viene fornito con ncftpget e ncftpput che tenterà ciascuno di caricare / scaricare un singolo file e restituire un codice di errore descrittivo in caso di problemi. Vedi & # 8220; Diagnostics & # 8221; sezione della man page .

Penso che sia più semplice eseguire ftp e controllare il codice di uscita di ftp se qualcosa è andato storto.

L'ho fatto come nell'esempio seguente:

# ...
ftp -i -n $HOST 2>&1 1> $FTPLOG << EOF
quote USER $USER
quote PASS $PASSWD
cd $RFOLDER
binary
put $FOLDER/$FILE.sql.Z $FILE.sql.Z
bye
EOF

# Check the ftp util exit code (0 is ok, every else means an error occurred!)
EXITFTP=$?
if test $EXITFTP -ne 0; then echo "$D ERROR FTP" >> $LOG; exit 3; fi
if (grep "^Not connected." $FTPLOG); then echo "$D ERROR FTP CONNECT" >> $LOG; fi 
if (grep "No such file" $FTPLOG); then echo "$D ERROR FTP NO SUCH FILE" >> $LOG; fi 
if (grep "access denied" $FTPLOG ); then echo "$D ERROR FTP ACCESS DENIED" >> $LOG; fi
if (grep "^Please login" $FTPLOG ); then echo "$D ERROR FTP LOGIN" >> $LOG; fi

Modifica: Per rilevare errori, grep l'output del comando ftp. Ma non è davvero la soluzione migliore.

Non so quanto sei familiare con uno Scriptlanguage come Perl, Python o Ruby. Hanno tutti un modulo FTP che puoi usare. Ciò consente di verificare la presenza di errori dopo ogni comando. Ecco un esempio in Perl:

#!/usr/bin/perl -w
use Net::FTP;
$ftp = Net::FTP->new("example.net") or die "Cannot connect to example.net: $@";
$ftp->login("username", "password") or die "Cannot login ", $ftp->message;
$ftp->cwd("/pub") or die "Cannot change working directory ", $ftp->message;
$ftp->binary;
$ftp->put("foo.bar") or die "Failed to upload ", $ftp->message;
$ftp->quit;

Affinché questa logica funzioni, l'utente deve reindirizzare STDERR e il comando ftp come di seguito

ftp -i -n $HOST >$FTPLOG 2>&1 << EOF

Il comando seguente assegnerà sempre 0 (esito positivo) poiché il comando ftp non restituirà l'esito positivo o negativo. Quindi l'utente non dovrebbe dipendere da esso

EXITFTP=$?

pessima risposta lo so, ma che ne dici di ottenere le fonti ftp e vedere di persona

Mi piace la soluzione di Anurag, per il problema dei byte trasferiti ho esteso il comando con grep -v " byte "

ie

grep " ^ 530 " ftp_out2.txt | grep -v " byte "

-Invece di 530 puoi usare tutti i codici di errore come ha fatto Anurag.

Hai detto che volevi FTP lì il file, ma non hai detto se il normale client FTP BSD fosse o meno l'unico modo in cui volevi portarlo lì. BSD FTP non ti fornisce un codice di ritorno per le condizioni di errore che richiedono tutto quel parsing, ma ci sono tutta una serie di altri programmi Unix che possono essere usati per trasferire file tramite FTP se tu o il tuo amministratore li installerete. Ti fornirò alcuni esempi di modi per trasferire un file tramite FTP pur rilevando tutte le condizioni di errore con piccole quantità di codice.

FTPUSER è il nome di accesso dell'utente ftp

FTPPASS è la tua password ftp

FILE è il file locale che si desidera caricare senza alcuna informazione sul percorso (es. file1.txt, non /whatever/file1.txt o qualunque / file1.txt

FTPHOST è la macchina remota su cui si desidera FTP

REMOTEDIR è un PERCORSO ASSOLUTO nella posizione sul computer remoto che si desidera caricare

Ecco gli esempi:

curl --user $ FTPUSER: $ FTPPASS -T $ FILE ftp: // $ FTPHOST /% 2f $ REMOTEDIR

ftp-upload --host $ FTPHOST --utente $ FTPUSER - password $ FTPPASS - come $ REMOTEDIR / $ FILE $ FILE

tnftp -u ftp: // $ FTPUSER: $ FTPPASS @ $ FTPHOST /% 2f $ REMOTEDIR / $ FILE $ FILE

wput $ FILE ftp: // $ FTPUSER: $ FTPPASS @ $ FTPHOST /% 2f $ REMOTEDIR / $ FILE

Tutti questi programmi restituiranno un codice di uscita diverso da zero se qualcosa va storto, insieme al testo che indica ciò che è fallito. Puoi testarlo e poi fare quello che vuoi con l'output, registrarlo, inviarlo via email, ecc. Come desideri.

Si noti tuttavia quanto segue:

  1. "% 2f " viene utilizzato negli URL per indicare che il seguente percorso è un percorso assoluto sul computer remoto. Tuttavia, se il tuo server FTP ti esegue il chroot, non sarai in grado di aggirare questo.

  2. per i comandi sopra che utilizzano un URL effettivo ( ftp: // etc ) al server con l'utente e password incorporate, il nome utente e la password DEVONO essere codificati nell'URL se contengono caratteri speciali.

  3. In alcuni casi puoi essere flessibile con la directory remota come assoluta e il file locale come solo il semplice nome del file una volta che hai familiarità con la sintassi di ciascun programma. Potrebbe essere sufficiente aggiungere una variabile di ambiente della directory locale o semplicemente hardcode tutto.

  4. SE davvero, DEVI assolutamente usare un normale client FTP, un modo per testare il fallimento è, all'interno del tuo script, incluso prima un comando che METTE il file, seguito da un altro che fa lo stesso file restituendolo con un nome diverso. Dopo la chiusura dell'FTP, è sufficiente verificare l'esistenza del file scaricato nello script della shell o persino eseguirne il checksum rispetto all'originale per assicurarsi che sia stato trasferito correttamente. Sì, questo puzza, ma secondo me è meglio avere un codice che sia facile da leggere che fare tonnellate di analisi per ogni possibile condizione di errore. BSD FTP non è poi così eccezionale.

Ecco quello con cui finalmente sono andato. Grazie per tutto l'aiuto. Tutte le risposte aiutano a guidarmi nella giusta direzione. Potrebbe essere un po 'eccessivo, controllando sia il risultato che il registro, ma dovrebbe coprire tutte le basi.

echo "open ftp_ip
pwd
binary    
lcd /out
cd /in
mput datafile.csv
quit"|ftp -iv > ftpreturn.log

ftpresult=$?

bytesindatafile=`wc -c datafile.csv | cut -d " " -f 1`    
bytestransferred=`grep -e '^[0-9]* bytes sent' ftpreturn.log | cut -d " " -f 1`    
ftptransfercomplete=`grep -e '226 ' ftpreturn.log | cut -d " " -f 1`

echo "-- FTP result code: $ftpresult" >> ftpreturn.log
echo "-- bytes in datafile: $bytesindatafile bytes" >> ftpreturn.log
echo "-- bytes transferred: $bytestransferred bytes sent" >> ftpreturn.log

if [ "$ftpresult" != "0" ] || [ "$bytestransferred" != "$bytesindatafile" ] || ["$ftptransfercomplete" != "226" ]    
then    
  echo "-- *abend* FTP Error occurred" >> ftpreturn.log    
  mailx -s 'FTP error' `cat email.lst` < ftpreturn.log
else    
  echo "-- file sent via ftp successfully" >> ftpreturn.log    
fi

Perché non archiviare tutto l'output del comando in un file di registro, quindi controllare il codice di ritorno dal comando e, se non è 0, inviare il file di registro nell'e-mail?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top