Bash: Check if remote directory exists using FTP

12,736

Solution 1

To solve this, do as follows:

  1. To ensure that you only use one FTP connection, you create the input (FTP commands) as an output of a shell script

    E.g.

    $ cat a.sh
    cd /home/test1
    mkdir /home/test1/test2
    
    $ ./a.sh | ftp $Your_login_and_server > /your/log 2>&1
    
  2. To allow the FTP to test if a directory exists, you use the fact that "DIR" command has an option to write to file

     # ...continuing a.sh
     # In a loop, $CURRENT_DIR is the next subdirectory to check-or-create
     echo "DIR $CURRENT_DIR $local_output_file" 
     sleep 5 # to leave time for the file to be created
     if (! -s $local_output_file)
     then
        echo "mkdir $CURRENT_DIR"
     endif
    

    Please note that "-s" test is not necessarily correct - I don't have acccess to ftp now and don't know what the exact output of running DIR on non-existing directory will be - cold be empty file, could be a specific error. If error, you can grep the error text in $local_output_file

  3. Now, wrap the step #2 into a loop over your individual subdirectories in a.sh

Solution 2

    #!/bin/bash

    FTP_HOST=prep.ai.mit.edu
    FTP_USER=anonymous
    [email protected]
    DIRECTORY=/foo                   # /foo does not exist, /pub exists
    LOCAL_LOG=/tmp/foo.log
    ERROR="Failed to change directory"

    ftp -n $FTP_HOST << EOF | tee -a ${LOCAL_LOG} | grep -q "${ERROR}"
    quote USER ${FTP_USER}
    quote pass ${FTP_PASS}
    cd ${DIRECTORY}
    EOF

    if [[ "${PIPESTATUS[2]}" -eq 1 ]]; then
      echo ${DIRECTORY} exists
    else
      echo ${DIRECTORY} does not exist
    fi

Output:

/foo does not exist


If you want to suppress only the messages in ${LOCAL_LOG}:

ftp -n $FTP_HOST <<! | grep -v "Cannot create a file" >> ${LOCAL_LOG}
Share:
12,736
grim
Author by

grim

Updated on August 23, 2022

Comments

  • grim
    grim almost 2 years

    I'm writing a bash script to send files from a linux server to a remote Windows FTP server. I would like to check using FTP if the folder where the file will be stored exists before attempting to create it. Please note that I cannot use SSH nor SCP and I cannot install new scripts on the linux server. Also, for performance issues, I would prefer if checking and creating the folders is done using only one FTP connection.

    Here's the function to send the file:

    sendFile() {
        ftp -n $FTP_HOST <<! >> ${LOCAL_LOG}
            quote USER ${FTP_USER}
            quote PASS ${FTP_PASS}
            binary
            $(ftp_mkdir_loop "$FTP_PATH")
            put ${FILE_PATH} ${FTP_PATH}/${FILENAME}
            bye
    !
    }
    

    And here's what ftp_mkdir_loop looks like:

    ftp_mkdir_loop() {
        local r
        local a
        r="$@"
        while [[ "$r" != "$a" ]]; do
          a=${r%%/*}
          echo "mkdir $a"
          echo "cd $a"
          r=${r#*/}
        done
    }
    

    The ftp_mkdir_loop function helps in creating all the folders in $FTP_PATH (Since I cannot do mkdir -p $FTP_PATH through FTP).

    Overall my script works but is not "clean"; this is what I'm getting in my log file after the execution of the script (yes, $FTP_PATH is composed of 5 existing directories):

    (directory-name) Cannot create a file when that file already exists.
    Cannot create a file when that file already exists.
    Cannot create a file when that file already exists.
    Cannot create a file when that file already exists.
    Cannot create a file when that file already exists.