Проверка кодов возврата ftp из скрипта Unix - PullRequest
3 голосов
/ 26 сентября 2008

В настоящее время я создаю ночную работу, которая вызывает скрипт Unix, который, в свою очередь, создает и передает файл, используя ftp. Я хотел бы проверить все возможные коды возврата. Страница man для ftp не содержит кодов возврата. Кто-нибудь знает, где найти список? Кто-нибудь с опытом с этим? У нас есть другие сценарии, которые grep для определенных возвращаемых строк в журнале, и они отправляют электронное письмо в случае ошибки. Однако они часто пропускают непредвиденные коды. Затем я помещаю причину в журнал и электронную почту.

Ответы [ 9 ]

7 голосов
/ 26 сентября 2008

Команда ftp не возвращает ничего, кроме нуля, в большинстве реализаций, с которыми я сталкивался.

Намного лучше обрабатывать трехзначные коды в журнале - и если вы отправляете двоичный файл, вы можете проверить, что отправленные байты были правильными.

Трехзначные коды называются «серийными кодами», и список можно найти здесь

5 голосов
/ 14 декабря 2010

Я написал сценарий для передачи только одного файла за раз, и в этом сценарии используйте grep для проверки сообщения 226 Transfer complete. Если он его находит, grep возвращает 0.

ftp -niv < "$2"_ftp.tmp | grep "^226 "
4 голосов
/ 28 сентября 2008

Установите пакет ncftp . Он поставляется с ncftpget и ncftpput , которые будут при каждой попытке загружать / скачивать отдельный файл и возвращать с описательным кодом ошибки в случае возникновения проблемы. См. Раздел «Диагностика» справочной страницы .

3 голосов
/ 26 сентября 2008

Я думаю, что проще запустить 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

Редактировать: Чтобы ловить ошибки, я извлекаю результаты команды 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;

Чтобы эта логика работала, пользователю необходимо также перенаправить STDERR из команды ftp, как показано ниже

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

Команда ниже всегда будет назначать 0 (успех), потому что команда ftp не вернет успех или неудачу. Поэтому пользователь не должен зависеть от этого

EXITFTP=$?
1 голос
/ 23 сентября 2010

Мне нравится решение от Anurag, для проблемы с передачей байтов я расширил команду командой grep -v "bytes"

т.е.

grep "^ 530" ftp_out2.txt | grep -v "byte"

вместо 530 вы можете использовать все коды ошибок, как это делал Anurag.

1 голос
/ 26 сентября 2008

Хромой ответ, я знаю, но как насчет получения исходников ftp и убедитесь сами

0 голосов
/ 31 января 2009

Вы сказали, что хотите отправить файл туда по FTP, но не сказали, был ли обычный FTP-клиент BSD единственным способом получить его там. BSD FTP не дает вам код возврата для условий ошибки, требующих всего этого анализа, но есть целый ряд других программ Unix, которые можно использовать для передачи файлов по FTP, если вы или ваш администратор их установите. Я приведу несколько примеров способов передачи файла по FTP, при этом перехватывая все ошибки с небольшим количеством кода.

FTPUSER - ваше имя пользователя ftp

FTPPASS ваш пароль FTP

ФАЙЛ - это локальный файл, который вы хотите загрузить без какой-либо информации о пути (например, file1.txt, а не /whwhat/file1.txt или любой другой файл / 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. «% 2f» используется в URL-адресах, чтобы указать, что следующий путь является абсолютным путем на удаленном компьютере. Однако, если ваш FTP-сервер поддерживает вас, вы не сможете это обойти.

  2. для вышеприведенных команд, использующих фактический URL-адрес ( ftp: // etc ) для сервера со встроенными в него именем пользователя и паролем, имя пользователя и пароль ДОЛЖНЫ быть закодированы в виде URL, если содержит специальные символы.

  3. В некоторых случаях вы можете проявить гибкость, если удаленный каталог является абсолютным, а локальный файл - простым именем файла, если вы знакомы с синтаксисом каждой программы. Возможно, вам просто нужно добавить переменную среды локального каталога или просто жестко закодировать все.

  4. ЕСЛИ вы действительно, абсолютно ДОЛЖНЫ использовать обычный FTP-клиент, один из способов проверить его на наличие ошибок - в вашем скрипте, включив сначала команду PUTs для файла, а затем другую, которая выполняет GET того же самого файл, возвращающий его под другим именем. После завершения работы FTP просто проверьте наличие загруженного файла в сценарии оболочки или даже сравните его с оригиналом, чтобы убедиться в правильности его передачи. Да, это воняет, но, на мой взгляд, лучше иметь код, который легко читается, чем делать множество разборов для каждого возможного состояния ошибки. BSD FTP просто не так уж и хорош.

0 голосов
/ 03 октября 2008

Вот что я наконец-то сделал. Спасибо за помощь. Все ответы помогают вести меня в правильном направлении. Это может быть немного излишним, проверяя и результат, и журнал, но он должен охватывать все базы.

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
0 голосов
/ 26 сентября 2008

Почему бы не сохранить все выходные данные команды в файле журнала, а затем проверить код возврата команды и, если он не равен 0, отправить файл журнала в электронном письме?

...