bash中的ftp脚本

时间:2011-01-10 09:56:23

标签: bash ftp

我有以下脚本将文件推送到远程位置:

#!/usr/bin/bash
HOST1='a.b.c.d'
USER1='load'
PASSWD1='load'
DATE=`date +%Y%m%d%H%M`
DATE2=`date +%Y%m%d%H`
DATE3=`date +%Y%m%d`
FTPLOGFILE=/logs/Done.$DATE2.log
D_FOLDER='/dir/load01/input'

PUTFILE='file*un'
ls $PUTFILE | while read file
do
  echo "${file} transfered at $DATE" >> /logs/$DATE3.log
done

ftp -n -v $HOST1 <<SCRIPT >> ${FTPLOGFILE} 2>&1
quote USER $USER1
quote PASS $PASSWD1
cd $D_FOLDER
ascii
prompt off
mput /data/file*un 
quit
SCRIPT

mv *un test/

ls test/*un | awk '{print("mv "$1" "$1)}' | sed 's/\.un/\.processed/2' |sh
rm *unl

我收到此错误输出:

200 PORT command successful.
553 /data/file1.un: A file or directory in the path name does not exist.
200 PORT command successful.

3 个答案:

答案 0 :(得分:5)

一些改进:

#!/usr/bin/bash
HOST1='a.b.c.d'
USER1='load'
PASSWD1='load'
read Y m d H M <<<$(date "+%Y %m %d %H %M")    # only one call to date
DATE='$Y$m$d$H$M'
DATE2='$Y$m$d$H'
DATE3='$Y$m$d'
FTPLOGFILE=/logs/Done.$DATE2.log
D_FOLDER='/dir/load01/input'

PUTFILE='file*un'
for file in $PUTFILE    # no need for ls
do
  echo "${file} transfered at $DATE"
done >> /logs/$DATE3.log    # output can be done all at once at the end of the loop.

ftp -n -v $HOST1 <<SCRIPT >> ${FTPLOGFILE} 2>&1
quote USER $USER1
quote PASS $PASSWD1
cd $D_FOLDER
ascii
prompt off
mput /data/file*un 
quit
SCRIPT

mv *un test/

for f in test/*un    # no need for ls and awk
do
  mv "$f" "${f/%.un/.processed}"
done

rm *unl

我建议使用小写或混合大小写变量来减少名称与shell变量冲突的可能性。

所有这些目录是否真的直接位于根目录之外?

答案 1 :(得分:0)

Ftp到远程站点并手动执行ftp命令。发生错误时,环顾四周看看是什么原因。 (如果您不知道ftp命令行,请使用“help”。)

可能/data目录不存在。有没有人最近重新组织了上传目录,或者可能移动了ftp服务器的根目录?

答案 2 :(得分:0)

脚本化FTP会话的问题是,如果FTP向stdout报告错误,则认为它已正确执行。因此,错误地收集错误是非常困难的,因为它只会在灾难性的事情上返回失败。如果您需要的不仅仅是最简单的命令列表,那么您应该使用expect或者java或perl程序之类的东西来轻松测试每个动作的结果。

那就是说,你可以运行ftp作为一个协同进程,或者设置它以便它在后台运行,它的stdin和stdout适合命名管道,或者某些结构就像你可以在决定传入下一个命令的内容之前,先读取并解析一个命令的输出。

循环在case语句上的读取循环,它测试已知响应并相应地运行,是一个可以接受的全bash版本。如果你总是用一个返回固定和已知值的image命令终止每个命令块,你可以扫描已知错误,并在case语句中检查该命令的返回,当你得到“sentinal”返回循环并读取下一个输入。不过,这会产生一个较大且相当复杂的shell脚本。

另外,当你得到(例如)一个5[0-9][0-9] *)返回时,你需要测试它实际上并不是“553字节*”,因为ftp也会这样做。

在没有包含代码示例的情况下为答案的长度道歉 - 我只是想提一些在评论中不可读的想法和警告。