2011-02-04 17 views
9

Necesito recuperar el código de estado de salida de un programa de línea de comando. No se preocupe, usé $ ?. Pero para ftp, incluso si no se conecta, abre el shell ftp, por lo que no puedo entender que la conexión no se haya realizado.Obteniendo el código de estado de salida del comando 'ftp' en el shell de linux

Prueba este código para entender:

#!/bin/sh 

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

exit 0 

Cualquier ayuda? Gracias Filippo

+0

Puede simplificar enormemente el código: if ftp ...; entonces ...; else ...; fi No es necesario comprobar explícitamente $? –

Respuesta

17

Usted debe buscar el mensaje de éxito de comando ftp en lugar de buscar un estado. Es "226 Transferencia completa". Puede confirmarlo con ftp manual en su 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) 

Aquí hay un script de ejemplo.

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

¡Gracias por su respuesta! Es lo mismo que hice, basado en la solución publicada por ayush, usando dos archivos para la salida para obtener el mensaje de error. – Possa

1

algunos guiones hacen -

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 

Salvo que lo anterior no siempre funciona - la mayoría de los clientes FTP, siempre salga con un estado de 0. Esto lleva a feos "falsos negativos": la la transferencia de archivos falla, pero el script no detecta el problema.

Una forma de verificar que una transferencia de archivos se llevó a cabo - transferir de nuevo:

#!/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

Para la primera respuesta, para ser sincero, realmente no entiendo muy bien su solución. – Possa

+1

He trabajado en su primera solución y funcionó con una pequeña modificación: Ejecuto el ftp en modo detallado, si en el ftp.trabajado está presente el "226 Transferir OK", ¡entonces la transferencia se ha realizado! Elseif Recupero el mensaje de error de ftp.failed. Gracias! +1 para ti! – Possa

5

Si necesita descargar algo y ver si la descarga ha sido correcta, ¿por qué no utilizar wget? Es compatible con el protocolo FTP.

Se informará del estado de la descarga con varios códigos de retorno (Cita de página del manual):

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

Tengo que mkdir, cd, poner el archivo ... – Possa

+0

Así que intente usar el valor de lectura. – user562374

+1

No puedo instalar nada en las máquinas. – Possa

0

La última vez que necesitaba usar ftp en un guión, me puso tan frustrado con lo que por fin he encontrado una fuente de cliente FTP de licencia BSD y simplemente lo modificó para darle el comportamiento que necesitaba, y se utiliza eso en lugar de la versión provista con el sistema operativo.

feo, pero la profundidad de abolladuras a nivel de la cabeza en la pared del cubo estaba empezando a ser ridícula

1

pruebe las siguientes secuencias de comandos.

copiar:

#!/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 

Para mover:

#!/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 

Éstos son algunos casos de prueba:

Para la reproducción.

$ ./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 

Para mudanza.

$ ./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 

Actualización: Recuerde leer man 5 netrc

0

Otra forma de evitar esto es para comprobar si tiene el archivo en el servidor después de la transferencia!

Algo así como ...

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

Si no está ahí, entonces no transfirió con éxito!

Cuestiones relacionadas