从Unix脚本中检查ftp返回代码

问题描述:

我目前正在创建一个通宵调用Unix脚本的作业,该脚本依次使用ftp创建和传输文件。我想检查所有可能的返回码。 ftp的手册页未列出返回码。有谁知道在哪里可以找到清单?任何有此经验的人?我们有其他一些脚本,它们会记录日志中的某些返回字符串,并在发生错误时发送电子邮件。但是,他们经常错过未曾预料的代码。 然后我将原因放入日志和电子邮件中。从Unix脚本中检查ftp返回代码

+0

感谢你们,你们可能知道,我的Unix脚本并不是那么遥远。我基本上是由过去在这里工作的人从其他脚本开始工作的。不过,我想让它比我目前发现的更加防弹。我很感激迄今为止所有的答案。 – 2008-09-26 15:49:35

+0

基本上我的代码到目前为止如下:回声“打开$ ftpip pwd二进制lcd /输出cd /输入$ datafile退出”| ftp -iv> $ ftpreturn -v选项看起来像我需要的。但是$ ftpreturn变量是空白的。该文件没有获得ftp'd并且正在失败。我错过了什么? – 2008-09-26 15:51:02

ftp命令不会返回上大多数实现零以外的任何东西,我已经遇到。

处理日志中的三位数字代码会更好 - 如果您发送的是二进制文件,则可以检查发送的字节是否正确。

三位数的代码被称为“码序列”和一个列表,可以发现here

+0

对不起是一个痛苦,但我有2个问题。 1)但日志在哪里?我认为它会在$ ftpreturn。 2)如何检查发送的字节? – 2008-09-26 16:35:33

为什么不直接将命令的所有输出存储到日志文件中,然后检查命令的返回码,如果不是0,则在电子邮件中发送日志文件?

跛脚的答案,我知道,但如何让ftp的来源,看看自己

+0

我该如何解决这个问题? – 2008-09-26 16:35:02

我认为这是更容易地运行FTP和检查FTP的退出代码,如果事情出了错。

我这样做像下面的例子:

# ... 
ftp -i -n $HOST 2>&1 1> $FTPLOG << EOF 
quote USER $USER 
quote PASS $PASSWD 
cd $RFOLDER 
binary 
put $FOLDER/$FILE.sql.Z $FILE.sql.Z 
bye 
EOF 

# Check the ftp util exit code (0 is ok, every else means an error occurred!) 
EXITFTP=$? 
if test $EXITFTP -ne 0; then echo "$D ERROR FTP" >> $LOG; exit 3; fi 
if (grep "^Not connected." $FTPLOG); then echo "$D ERROR FTP CONNECT" >> $LOG; fi 
if (grep "No such file" $FTPLOG); then echo "$D ERROR FTP NO SUCH FILE" >> $LOG; fi 
if (grep "access denied" $FTPLOG); then echo "$D ERROR FTP ACCESS DENIED" >> $LOG; fi 
if (grep "^Please login" $FTPLOG); then echo "$D ERROR FTP LOGIN" >> $LOG; fi 

编辑:捕捉错误的grep我ftp命令的输出。但它确实不是最好的解决方案。

我不知道你有多熟悉Perl,Python或Ruby等Scriptlanguage。他们都有一个可以使用的FTP模块。这使您可以在每个命令后检查错误。这里有一个Perl的例子:

#!/usr/bin/perl -w 
use Net::FTP; 
$ftp = Net::FTP->new("example.net") or die "Cannot connect to example.net: [email protected]"; 
$ftp->login("username", "password") or die "Cannot login ", $ftp->message; 
$ftp->cwd("/pub") or die "Cannot change working directory ", $ftp->message; 
$ftp->binary; 
$ftp->put("foo.bar") or die "Failed to upload ", $ftp->message; 
$ftp->quit; 

安装ncftp包。它配备了ncftpgetncftpput,每个都会尝试上传/下载单个文件,并在出现问题时返回描述性错误代码。请参阅man page的“诊断”部分。

这是我终于跟着去的。感谢所有的帮助。所有的答案都能帮助我走向正确的方向。 它可能有点矫枉过正,检查结果和日志,但它应该涵盖所有的基础。

echo "open ftp_ip 
pwd 
binary  
lcd /out 
cd /in 
mput datafile.csv 
quit"|ftp -iv > ftpreturn.log 

ftpresult=$? 

bytesindatafile=`wc -c datafile.csv | cut -d " " -f 1`  
bytestransferred=`grep -e '^[0-9]* bytes sent' ftpreturn.log | cut -d " " -f 1`  
ftptransfercomplete=`grep -e '226 ' ftpreturn.log | cut -d " " -f 1` 

echo "-- FTP result code: $ftpresult" >> ftpreturn.log 
echo "-- bytes in datafile: $bytesindatafile bytes" >> ftpreturn.log 
echo "-- bytes transferred: $bytestransferred bytes sent" >> ftpreturn.log 

if [ "$ftpresult" != "0" ] || [ "$bytestransferred" != "$bytesindatafile" ] || ["$ftptransfercomplete" != "226" ]  
then  
    echo "-- *abend* FTP Error occurred" >> ftpreturn.log  
    mailx -s 'FTP error' `cat email.lst` < ftpreturn.log 
else  
    echo "-- file sent via ftp successfully" >> ftpreturn.log  
fi 

你说你想FTP那里的文件,但你没有说是否常规的BSD FTP客户端是唯一的方式,你想要它在那里。 BSD FTP并不会为错误条件提供返回代码,因此需要进行所有解析,但是如果您或您的管理员将安装它们,则可以使用一系列其他Unix程序来通过FTP传输文件。我会给你一些通过FTP传输文件的方法,同时还能用少量代码捕获所有错误条件。

名为ftpuser是你的FTP用户的登录名

FTPPASS是你的FTP密码

FILE是你想不带任何路径信息上传(比如FILE1.TXT,不/whatever/file1.txt本地文件或什么/ FILE1.TXT

FTPHOST是要FTP到

REMOTEDIR远程机器是一个绝对路径的位置,您要上传到

在远程机器上10

这里是例子:

卷曲--user $名为ftpuser:$ FTPPASS -T $文件时ftp:// $ FTPHOST /%2F $ REMOTEDIR

FTP上传--host $ FTPHOST - 用户$名为ftpuser --password $ FTPPASS --as $ REMOTEDIR/$文件$ FILE

tnftp -u的ftp:// $名为ftpuser:$ FTPPASS @ $ FTPHOST /%2F $ REMOTEDIR/$文件$ FILE

wput $ FILE ftp:// $ FTPUSER:$ FTPPASS @ $ FTPHOST /%2f $ REMOTEDIR/$ FILE

所有这些pr如果出现任何错误,则图形将返回非零退出代码,以及指示失败的文本。你可以测试这个,然后做任何你想要的输出,记录它,给它发电子邮件等,如你所愿。

不过请注意以下内容:

  1. “%2F”在URL中使用,以表明以下路径是在远程机器上的绝对路径。但是,如果您的FTP服务器chroots你,你将无法绕过这一点。

  2. 对于上述使用实际URL(ftp://etc)的服务器的用户名和密码嵌入到服务器中,如果用户名和密码包含特殊字符,则必须进行URL编码。

  3. 在某些情况下,只要熟悉每个程序的语法,就可以灵活地使用远程目录作为绝对文件,本地文件只是普通文件名。你可能只需要添加一个本地目录环境变量或者只是硬编码一切。

  4. 如果您确实绝对必须使用普通的FTP客户端,您可以通过以下方式之一来测试故障:在脚本内部,包括首先执行PUT文件的命令,然后是另一个执行同一文件的GET以不同的名字返回它。 FTP退出后,只需在shell脚本中测试下载文件的存在性,或者甚至针对原始文件检查下载文件,以确保其正确传输。是的,这太臭了,但在我看来,最好是让代码易于阅读,而不是为每个可能的错误条件进行大量的解析。 BSD FTP并不是那么棒。

我喜欢从阿努拉格溶液,对于字节转移的问题,我已经延长使用grep -v命令 “字节”

grep的 “^ 530” ftp_out2。txt | grep -v“byte”

-insert of 530 you can use all error codes as Anurag did。

我写了一个脚本,一次只能传输一个文件,并在该脚本中使用grep来检查226 Transfer complete消息。如果它发现它,grep返回0.

ftp -niv < "$2"_ftp.tmp | grep "^226 "