Bash: check if remote directory exists using FTP

I am writing a bash script to send files from 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 trying to create it. Please note that I cannot use SSH or SCP and I cannot install new scripts on the linux server. Also, for performance issues, I would prefer that checking and creating folders is done using just 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 this is what it looks like ftp_mkdir_loop

:

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

      

The function ftp_mkdir_loop

helps to create all folders in $FTP_PATH

(since I cannot execute mkdir -p $FTP_PATH

via FTP).

In general, my script works, but not "clean"; this is what I get in my log file after executing the script (yes, it $FTP_PATH

consists 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.

      

+3


source to share


2 answers


To fix this problem, do the following:



  • To make sure you only use one FTP connection, you create an input (FTP commands) as the output of a shell script

    eg.

    $ cat a.sh
    cd /home/test1
    mkdir /home/test1/test2
    
    $ ./a.sh | ftp $Your_login_and_server > /your/log 2>&1
    
          

  • To allow FTP to check if a directory exists, you are using the fact that the "DIR" command has the ability to write to a 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 the test is "-s"

    not always correct - I don't have access to ftp now and I don't know what the exact output of a running DIR to a non-existent directory would be - cold be empty file, could be a specific error. If error, you can grep the error text in $ local_output_file

  • Now complete step # 2 by looping over your individual subdirectories in a.sh

+1


source


    #!/bin/bash

    FTP_HOST=prep.ai.mit.edu
    FTP_USER=anonymous
    FTP_PASS=foobar@example.com
    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 only want to suppress messages in ${LOCAL_LOG}

:
ftp -n $FTP_HOST <<! | grep -v "Cannot create a file" >> ${LOCAL_LOG}

      

+1


source







All Articles