3

我目前正在创建一个通宵作业,该作业调用一个 Unix 脚本,该脚本又使用ftp. 我想检查所有可能的返回码。的手册页ftp没有列出返回码。有谁知道在哪里可以找到清单?有这方面经验的人吗?我们还有其他脚本在日志中对某些返回字符串进行 grep,并在出错时发送电子邮件。然而,他们经常错过意料之外的代码。然后我将原因放入日志和电子邮件中。

4

9 回答 9

7

在我遇到的大多数实现中,该ftp命令不会返回零以外的任何值。

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

三位数代码称为“系列代码”,可以在此处找到列表

于 2008-09-26T15:03:41.680 回答
5

我编写了一个脚本,一次只传输一个文件,并在该脚本中用于grep检查226 Transfer complete消息。如果找到,则grep返回 0。

ftp -niv < "$2"_ftp.tmp | grep "^226 "
于 2010-12-14T18:27:57.353 回答
4

安装ncftp包。它带有ncftpgetncftpput,它们都将尝试上传/下载单个文件,如果出现问题,则返回描述性错误代码。请参阅手册页的“诊断”部分。

于 2008-09-28T01:30:04.660 回答
3

我认为如果出现问题,运行 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 等脚本语言有多熟悉。它们都有一个可供您使用的 FTP 模块。这使您能够在每个命令之后检查错误。这是 Perl 中的一个示例:

#!/usr/bin/perl -w
use Net::FTP;
$ftp = Net::FTP->new("example.net") or die "Cannot connect to example.net: $@";
$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;

要使此逻辑正常工作,用户还需要从 ftp 命令重定向 STDERR,如下所示

ftp -i -n $HOST >$FTPLOG 2>&1 << EOF

下面的命令将始终分配 0(成功),因为 ftp 命令不会返回成功或失败。所以用户不应该依赖它

EXITFTP=$?
于 2008-09-26T15:57:47.010 回答
1

蹩脚的答案我知道,但是如何获取 ftp 源并自己查看

于 2008-09-26T15:03:19.420 回答
1

我喜欢 Anurag 的解决方案,对于字节传输问题,我使用 grep -v "bytes" 扩展了命令

IE

grep "^530" ftp_out2.txt | grep -v "字节"

- 而不是 530,您可以像 Anurag 那样使用所有错误代码。

于 2010-09-23T10:34:07.460 回答
0

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

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
于 2008-10-03T19:18:51.903 回答
0

你说你想把文件 FTP 到那里,但你没有说普通的 BSD FTP 客户端是否是你想把它送到那里的唯一方法。BSD FTP 不会为需要所有解析的错误条件提供返回代码,但是如果您或您的管理员将安装它们,则可以使用一系列其他 Unix 程序通过 FTP 传输文件。我将为您提供一些通过 FTP 传输文件的方法示例,同时仍然使用少量代码捕获所有错误情况。

FTPUSER 是您的 ftp 用户登录名

FTPPASS 是您的 ftp 密码

FILE 是您要上传的没有任何路径信息的本地文件(例如 file1.txt,而不是 /whatever/file1.txt 或whatever/file1.txt

FTPHOST 是您要通过 FTP 连接到的远程计算机

REMOTEDIR 是您要上传到的远程计算机上的位置的绝对路径

以下是示例:

curl --user $FTPUSER:$FTPPASS -T $FILE ftp://$FTPHOST/%2f$REMOTEDIR

ftp-upload --host $FTPHOST --user $FTPUSER --password $FTPPASS --as $REMOTEDIR/$FILE $FILE

tnftp -u ftp://$FTPUSER:$FTPPASS@$FTPHOST/%2f$REMOTEDIR/$FILE $FILE

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

如果出现任何问题,所有这些程序都将返回一个非零退出代码,以及指示失败的文本。您可以对此进行测试,然后根据需要对输出进行任何操作、记录、发送电子邮件等。

但请注意以下事项:

  1. URL 中使用“%2f”表示以下路径是远程计算机上的绝对路径。但是,如果您的 FTP 服务器对您进行 chroot,您将无法绕过它。

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

  3. 在某些情况下,一旦您熟悉了每个程序的语法,您就可以灵活地将远程目录设为绝对目录,将本地文件设为纯文件名。您可能只需要添加一个本地目录环境变量或对所有内容进行硬编码。

  4. 如果你真的,绝对必须使用常规的 FTP 客户端,你可以测试失败的一种方法是在你的脚本中,首先包括一个 PUT 文件的命令,然后是另一个执行相同文件的 GET 的命令,在不同的情况下返回它姓名。FTP 退出后,只需在您的 shell 脚本中测试下载的文件是否存在,或者甚至将其与原始文件进行校验,以确保它正确传输。是的,这很臭,但在我看来,拥有易于阅读的代码比对每种可能的错误情况进行大量解析要好。BSD FTP 并不是那么好。

于 2009-01-30T23:06:39.113 回答
-1

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

于 2008-09-26T15:03:02.570 回答