Я пишу сценарий оболочки BASH, чтобы загрузить все файлы в каталоге на удаленный сервер, а затем удалить их. Он будет запускаться каждые несколько часов через задание CRON.
Мой полный сценарий ниже. Основная проблема заключается в том, что часть, которая должна выяснить, успешно ли загружен файл или нет, не работает. Статус выхода команды SFTP всегда равен «0», независимо от того, действительно ли загрузка прошла успешно или нет.
Как я могу выяснить, правильно ли загружен файл, чтобы я мог знать, удалять его или оставить?
#!/bin/bash
# First, save the folder path containing the files.
FILES=/home/bob/theses/*
# Initialize a blank variable to hold messages.
MESSAGES=""
ERRORS=""
# These are for notifications of file totals.
COUNT=0
ERRORCOUNT=0
# Loop through the files.
for f in $FILES
do
# Get the base filename
BASE=`basename $f`
# Build the SFTP command. Note space in folder name.
CMD='cd "Destination Folder"\n'
CMD="${CMD}put ${f}\nquit\n"
# Execute it.
echo -e $CMD | sftp -oIdentityFile /home/bob/.ssh/id_rsa bob@ftp.example.edu
# On success, make a note, then delete the local copy of the file.
if [ $? == "0" ]; then
MESSAGES="${MESSAGES}\tNew file: ${BASE}\n"
(( COUNT=$COUNT+1 ))
# Next line commented out for ease of testing
#rm $f
fi
# On failure, add an error message.
if [ $? != "0" ]; then
ERRORS="${ERRORS}\tFailed to upload file ${BASE}\n"
(( ERRORCOUNT=$ERRORCOUNT+1 ))
fi
done
SUBJECT="New Theses"
BODY="There were ${COUNT} files and ${ERRORCOUNT} errors in the latest batch.\n\n"
if [ "$MESSAGES" != "" ]; then
BODY="${BODY}New files:\n\n${MESSAGES}\n\n"
fi
if [ "$ERRORS" != "" ]; then
BODY="${BODY}Problem files:\n\n${ERRORS}"
fi
# Send a notification.
echo -e $BODY | mail -s $SUBJECT bob@example.edu
Из-за некоторых операционных соображений, от которых у меня болит голова, я не могу использовать SCP. Удаленный сервер использует WinSSHD в Windows и не имеет привилегий EXEC, поэтому любые команды SCP завершаются с ошибкой с сообщением «Ошибка выполнения запроса на канале 0». Поэтому загрузка должна выполняться с помощью интерактивной команды SFTP.
Если вы пакетируете свой сеанс SFTP, статус выхода $?
сообщит вам, неудачный это перевод или нет.
echo "put testfile1.txt" > batchfile.txt
sftp -b batchfile.txt user@host
if [[ $? != 0 ]]; then
echo "Transfer failed!"
exit 1
else
echo "Transfer complete."
fi
Отредактировано для добавления: это то, что мы используем в рабочем сценарии, поэтому я уверен, что это действительно так. Мы не можем использовать scp, потому что некоторые из наших клиентов используют SCO Unix.
По традиции serverfault не ставит под сомнение предварительные условия, но я должен спросить: возможно ли для вас либо 1) смонтировать удаленную файловую систему через SMB, или 2) вместо этого использовать fuse / sshfs? (Здесь я предполагаю, что отправляющая машина - это Linux, поскольку вы используете bash и ssh.)
Чтобы ответить на ваш вопрос, я думаю, ваша проблема проста. Рассматривать:
quest@wonky:~$ false
quest@wonky:~$ if [ $? != "0" ] ; then echo asdf ; fi
asdf
quest@wonky:~$ if [ $? != "0" ] ; then echo asdf ; fi
Попробуйте вместо этого вот так:
quest@wonky:~$ false
quest@wonky:~$ res=$?
quest@wonky:~$ if [ $res != "0" ] ; then echo asdf ; fi
asdf
quest@wonky:~$ if [ $res != "0" ] ; then echo asdf ; fi
asdf
Чтобы объяснить: ваш второй оператор if "if [$?! =" 0 "]; then" проверяет статус выхода последнего оператора, который больше не sftp, а предыдущий оператор if.
Тогда мне интересно, действительно ли sftp выйдет с ненулевым значением, если у него возникнут проблемы с загрузкой файлов? Беглые тесты показывают, что у меня нет.
Использовать rsync(.exe)
и копаться в --remove-source-files
& co., не волнуйтесь даже о неудачных загрузках, он это сделает! ;-)
Да, вы можете связать это с помощью ssh, см. --rsh
Jarhead
как насчет запуска sftp Batch script в ОС Windows для обнаружения успеха / неудачи?
Я использую% errorlevel% для обнаружения успеха / неудачи, иногда% errorlevel% возвращается значением 0, но этот сеанс завершился ошибкой, и файл не загружается на сервер. мой сценарий ниже
как я могу правильно определить загруженный sftp? THX так много
@echo off
(echo cd %4
echo put %2
echo exit)>sftpScript.txt
sftp -b sftpScript.txt %3
set result=%errorlevel%
if result EQU 0 (
del sftpScript.txt
del %2
) else (
del sftpScript.txt
)
exit %result%
** отредактировано для фактического использования пакетного файла. Для расширения пакетного решения.
В копии sftp, которую я запускаю, командный файл завершается с ошибкой, даже если существует несколько команд за пределами точки ошибки
Согласно изначально опубликованной логике, проверяя $?, Вы проверяете результат всего пакета. Если вы согласны с удалением некоторых из файлов, которые БЫЛИ успешно переданы, создайте пакетный файл с помощью! Rm после каждого помещения. Если команда put не удалась,! Rm не запустится.
(for F in *.pgp
do
echo put $F
echo !rm $F
done;echo quit) > Batchfile ; sftp -b Batchfile user@targetServer