2011-02-04 8 views
9

Ho bisogno di riattivare il codice di stato di uscita da un programma a riga di comando. Nessun problema, ho usato $ ?. Ma per ftp, anche se non si connette, apre la shell ftp, quindi non sono in grado di capire che la connessione non ha avuto luogo.Ottenere il codice di stato di uscita dal comando "ftp" nella shell di linux

Prova questo codice per capire:

#!/bin/sh 

ftp 1234567 
OUT=$? 
if [ $OUT -eq 0 ];then 
    echo "ftp OK" 
else 
    echo "ftp Error: "$OUT 
fi 

exit 0 

Qualsiasi aiuto? Grazie Filippo

+0

È possibile semplificare notevolmente il codice: se ftp ...; poi ...; altro ...; Non è necessario controllare esplicitamente $? –

risposta

17

Si dovrebbe essere alla ricerca di un messaggio di successo dal comando ftp piuttosto che alla ricerca di uno stato. È "226 Trasferimento completato". Puoi confermarlo con ftp manual sul tuo sistema.

200 PORT command successful. 
150 Opening ASCII mode data connection for filename. 
226 Transfer complete. 
189 bytes sent in 0.145 seconds (0.8078 Kbytes/s) 

Ecco uno script di esempio.

FTPLOG=/temp/ftplogfile 
ftp -inv <<! > $FTPLOG 
open server 
user ftp pwd 
put filename 
close 
quit 
! 

FTP_SUCCESS_MSG="226 Transfer complete" 
if fgrep "$FTP_SUCCESS_MSG" $FTPLOG ;then 
    echo "ftp OK" 
else 
    echo "ftp Error: "$OUT 
fi 
exit 0 
+0

Grazie per la tua risposta! È la stessa cosa che ho fatto, basata sulla soluzione pubblicata da ayush, utilizzando due file per l'output per ottenere l'errore del messaggio. – Possa

1

alcuni script fanno -

ftp -n $HOST > /tmp/ftp.worked 2> /tmp/ftp.failed <<END_SCRIPT 
blah blah 
END_SCRIPT 

EXITSTATUS=$? 

if [ $EXITSTATUS != "0" ] 
then 
    # handle the error... 
fi 

Tranne che quanto sopra non sempre funziona - la maggior parte dei client FTP sempre uscita con lo stato 0. Questo porta a brutte "falsi negativi": il il trasferimento dei file fallisce, ma lo script non rileva il problema.

Un modo per verificare che un trasferimento di file ha avuto luogo - trasferirlo di nuovo:

#!/bin/sh 

ftp -n << END_SCRIPT 
open $1 
user $2 $3 
put $4 
get $4 retrieval.$$ 
bye 
END_SCRIPT 

if [ -f retrieval.$$ ] 
then 
    echo "FTP of $4 to $1 worked" 
    rm -f retrieval.$$ 
else 
    echo "FTP of $4 did not work" 
fi 
+0

Per la prima risposta, ad essere onesto, davvero non capisco molto bene la tua soluzione. – Possa

+1

Ho lavorato sulla tua prima soluzione e ha funzionato con una piccola modifica: Eseguo il ftp in modalità dettagliata, se in ftp.worked è presente "226 Transfer OK" quindi il trasferimento è stato eseguito! Elseif Ritrovo il messaggio di errore da ftp.failed. Grazie! +1 per te! – Possa

5

Se avete bisogno di scaricare qualcosa e vedere se il download è riuscito, perché non si usa wget? Supporta il protocollo FTP.

segnalerà lo stato del download con diversi codici di ritorno (citazione da pagina man):

EXIT STATUS 
    Wget may return one of several error codes if it encounters problems. 
    0 No problems occurred. 
    1 Generic error code. 
    2 Parse error---for instance, when parsing command-line options, the .wgetrc or .netrc... 
    3 File I/O error. 
    4 Network failure. 
    5 SSL verification failure. 
    6 Username/password authentication failure. 
    7 Protocol errors. 
    8 Server issued an error response. 
+0

Devo mkdir, cd, put file ... – Possa

+0

Quindi prova a usare wput. – user562374

+1

Non riesco ad installare nulla sulle macchine. – Possa

0

L'ultima volta che avevo bisogno di usare ftp in uno script, mi sono così frustrato con essa che ho finalmente trovato una fonte client ftp con licenza BSD e semplicemente modificato per dargli il comportamento di cui avevo bisogno, e utilizzati quello invece della versione fornita con il sistema operativo.

Brutto, ma la profondità di ammaccature a livello testa nella parete del cubo stava cominciando a diventare ridicola

1

provare il seguente script.

da copiare:

#!/bin/bash 
# cftp.sh 
# set -x 

FTPSERVER="$1" 
FTPPORT="$2" 
REMOTEDIR="$3" 

[[ "$REMOTEDIR" ]] || { echo -e "Usage: $0 <ftpserver> <ftpport> <remotedir> [file1] [file2] ..." > /dev/stderr ; exit 1 ; } 

L=$((BASH_ARGC-3)) 

LOCALFILES=("${BASH_ARGV[@]:0:$L}") 

RETCODE=0 

for LOCALFILE in "${LOCALFILES[@]}" 
do 
    THISRETCODE=0 
    [[ -f "$LOCALFILE" ]] || THISRETCODE=1 

    LOCALDIR="$(dirname "$LOCALFILE")" 
    LOCALFILENAME="$(basename "$LOCALFILE")" 

    [[ $THISRETCODE = 0 ]] && 
    /usr/bin/ftp -iv "$FTPSERVER" << EOF | grep -q '226 Transfer complete' || THISRETCODE=1 
    lcd $LOCALDIR 
    cd $REMOTEDIR 
    put $LOCALFILENAME 
EOF 

    RETCODE=$((RETCODE+THISRETCODE)) 
done 

exit $RETCODE 

Per spostare:

#!/bin/bash 
# mftp.sh 
# set -x 

FTPSERVER="$1" 
FTPPORT="$2" 
REMOTEDIR="$3" 

[[ "$REMOTEDIR" ]] || { echo -e "Usage: $0 <ftpserver> <ftpport> <remotedir> [file1] [file2] ..." > /dev/stderr ; exit 1 ; } 

L=$((BASH_ARGC-3)) 

LOCALFILES=("${BASH_ARGV[@]:0:$L}") 

RETCODE=0 

for LOCALFILE in "${LOCALFILES[@]}" 
do 
    THISRETCODE=0 
    [[ -f "$LOCALFILE" ]] || THISRETCODE=1 

    LOCALDIR="$(dirname "$LOCALFILE")" 
    LOCALFILENAME="$(basename "$LOCALFILE")" 

    [[ $THISRETCODE = 0 ]] && 
    /usr/bin/ftp -iv "$FTPSERVER" << EOF | grep -q '226 Transfer complete' || THISRETCODE=1 
    lcd $LOCALDIR 
    cd $REMOTEDIR 
    put $LOCALFILENAME 
EOF 

    [[ $THISRETCODE = 0 ]] && 
    /bin/rm -f "$LOCALFILE" || THISRETCODE=1 

    RETCODE=$((RETCODE+THISRETCODE)) 
done 

exit $RETCODE 

Ecco alcuni casi di test:

per la copia.

$ ./cftp.sh ; echo return code: $? 
Usage: ./cftp.sh <ftpserver> <ftpport> <remotedir> [file1] [file2] ... 
return code: 1 
$ ./cftp.sh ftpserver 21 /mnt/disk4/d0/test ; echo return code: $? 
return code: 0 
$ ./cftp.sh ftpserver 21 /mnt/disk4/d0/test cftp.sh mftp.sh ; echo return code: $? 
return code: 0 
$ ./cftp.sh ftpserver 21 /mnt/disk4/d0/test *ftp.sh ; echo return code: $? 
return code: 0 
$ ./cftp.sh ftpserver 21 /mnt/disk4/d0/test cftp.s ; echo return code: $? 
return code: 1 
$ ./cftp.sh ftpserver 21 /mnt/disk4/d0/test cftp.s mftp.s ; echo return code: $? 
return code: 2 
$ ./cftp.sh ftpserver 21 /mnt/disk4/d0/tes cftp.sh ; echo return code: $? 
return code: 1 

Per lo spostamento.

$ ./mftp.sh ftpserver 21 /mnt/disk4/d0/test cftp.sh ; echo return code: $? 
/bin/rm: cannot remove `cftp.sh': Permission denied 
return code: 1 
$ echo foo > /tmp/bar 
$ ./mftp.sh ftpserver 21 /mnt/disk4/d0/test /tmp/bar ; echo return code: $? 
return code: 0 
$ ls -lha /tmp/bar 
ls: cannot access /tmp/bar: No such file or directory 

Aggiornamento: Ricordati di leggere man 5 netrc

0

Un altro modo per aggirare questo è quello di verificare se si ha il file sul vaglia postale server!

Qualcosa di simile ...

if ![ -s "$INPUT_DIR/HOP_PSA_Transactions_$BATCH_ID.csv" ] 
 
then 
 
    ## No Transactions file 
 
    FAIL_TIME=`date +"%d-%m-%Y %H:%M"` 
 
\t echo "ERROR: File HOP_PSA_Transactions_$BATCH_ID.csv not found @ $FAIL_TIME" >>$LOGFILE_DIR$LOGFILE_NAME 
 
\t exit $ERR_NO_TRANS_FILE  
 
fi

Se non è lì allora non ha trasferito con successo!