Getting exit status code from 'ftp' command in linux shell

后端 未结 6 1145
半阙折子戏
半阙折子戏 2020-12-28 23:08

I need to retrive the exit status code from a command line program. No worries, I used $?. But for ftp, even if it doesn\'t connect, it opens the ftp shell, so I\'m not able

相关标签:
6条回答
  • 2020-12-28 23:09

    some scripts do -

    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 
    

    Except that the above doesn't always work - most FTP clients always exit with a status of 0. This leads to ugly "false negatives": the file transfer fails, but the script doesn't detect the problem.

    One way to verify that a file transfer took place - transfer it back:

    #!/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 讨论(0)
  • 2020-12-28 23:10

    If you need to download something and see if the download succeeded, why don't you use wget? It supports the FTP protocol.

    It will report the status of the download with several return codes (quote from man page):

    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 讨论(0)
  • 2020-12-28 23:11

    You should be looking for success message from ftp command rather than looking for a status. It's "226 Transfer complete". You can confirm it with ftp manual on your system.

    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)
    

    Here's a sample script.

    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 讨论(0)
  • 2020-12-28 23:12

    Another way around this is to check if you have the file on your server post transfer!

    Something like...

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

    If it's not there then it didn't transfer successfully!

    0 讨论(0)
  • 2020-12-28 23:25

    Try the following scripts.

    To copy:

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

    To move:

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

    Here are some test cases:

    For copying.

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

    For moving.

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

    Update: Remember to read man 5 netrc

    0 讨论(0)
  • 2020-12-28 23:28

    The last time I needed to use ftp in a script, I got so frustrated with it that I finally found a BSD-licensed ftp client source and simply modified it to give it the behavior I needed, and used that instead of the version provided with the OS.

    Ugly, but the depth of head-level dents in the cube wall was starting to get ridiculous

    0 讨论(0)
提交回复
热议问题