Bash: 使用FTP 检查远程目录是否存在

4
我正在编写一个bash脚本,将文件从Linux服务器发送到远程Windows FTP服务器。 我想在尝试创建文件夹之前,使用FTP检查存储文件的文件夹是否存在。 请注意,我不能使用SSH或SCP,并且我不能在Linux服务器上安装新脚本。此外,出于性能问题,我希望仅使用一个FTP连接来检查和创建文件夹。
这是发送文件的函数:
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
!
}

下面是 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
}
< p > ftp_mkdir_loop函数有助于在$FTP_PATH中创建所有文件夹(由于无法通过FTP执行mkdir -p $FTP_PATH)。

总体而言,我的脚本可以工作,但不是“干净”的; 在脚本执行后,这是我在日志文件中得到的内容(是的,$FTP_PATH由5个现有目录组成):

(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.
2个回答

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

输出:

/foo不存在


如果您只想消除${LOCAL_LOG}中的消息:

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

这里的建议是他应该执行每个目录组件一个ftp连接来测试cd,然后执行每个不存在的组件一个连接来使用mkdir,最后再执行一个连接来传输文件吗? - Etan Reisner
1
使用 $PIPESTATUS 来检查 FTP 中的错误是一个创意性的答案。但是根据 @EtanReisner 的评论,似乎会有太多的 FTP 连接。此外,我最终想要通过一个 FTP 连接来检查文件夹的存在并创建它们。 - grim
如果没有更好的答案,我会在期限结束时授予您奖励,因为我刚刚了解到$PIPESTATUS,而您的第二个答案仅抑制消息,虽然不完全回答了我的问题,但已经令人满意。 - grim
@grim 很不幸,我不知道有没有办法在FTP中测试目录而不触发错误(无论是从mkdir还是cd),我也不知道有没有办法在FTP会话中测试/捕获该错误,因此当与原始代码一起使用时,选择性静音可能是您能得到的最好的结果。 - Etan Reisner

1
这个问题可以通过以下方式解决:
  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


我无法实现这个解决方案。你能详细说明一下吗?我在Bash脚本方面还不是很熟练。 - grim
当我执行 DIR $CURRENT_DIR $local_output_file 时,出现了 ?Invalid command 的错误提示。请问 $local_output_file 是什么? - grim
@grim - 这是我编写的一个变量,用于保存您想要存储DIR输出的文件的名称。 - DVK
顺便说一下,对不存在的目录运行DIR的输出不会创建/更新本地输出文件。 - grim
请问你能为我澄清一些事情吗?在将输出重定向到 ftp 命令之前,a.sh 不是完全运行吗?如果是这样的话,本地输出文件“test”永远不会评估为 false,对吗? - grim
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接