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.
source to share
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
source to share
#!/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}
source to share