Сценарий оболочки для загрузки нескольких файлов FTP

Я пытаюсь загрузить несколько файлов из одной папки на ftp-сайт и написал этот скрипт:

#!/bin/bash
for i in '/dir/*'
do 
if [-f /dir/$i]; then
HOST='x.x.x.x'
USER='username'
PASSWD='password'
DIR=archives
File=$i

ftp -n $HOST << END_SCRIPT
quote USER $USER
quote PASS $PASSWD
ascii
put $FILE   
quit    
END_SCRIPT
fi     

Это дает мне следующую ошибку, когда я пытаюсь выполнить:

username@host:~/Documents/Python$ ./script.sh 
./script.sh: line 22: syntax error: unexpected end of file

Кажется, я не могу заставить это работать. Буду признателен за любую оказанную помощь.

Спасибо, Маянк


person maksaraswat    schedule 24.04.2012    source источник
comment
«Неожиданный конец файла» возникает из-за того, что у вас есть цикл for без соответствующего done в конце.   -  person Charles Duffy    schedule 24.04.2012
comment
Чтобы упростить задачу вашим помощникам, сделайте отступ в телах управляющих структур for, if и т. д. Спасибо!   -  person Jens    schedule 04.05.2012


Ответы (4)


Он жалуется, потому что ваш цикл for не имеет маркера done, указывающего на конец цикла. Вам также нужно больше пробелов в вашем if:

if [ -f "$i" ]; then

Напомним, что [ на самом деле является командой, и она не будет распознана, если не отображается как таковая.

И... если вы закавычите свой глобус (в for) таким образом, он не будет расширен. Там нет кавычек, но двойные кавычки при использовании $i. Вероятно, вы также не хотите включать часть /dir/ при использовании $i, так как она включена в ваш глобус.

person FatalError    schedule 24.04.2012
comment
Я внес предложенные вами изменения и получил следующую ошибку: user@host:~/Documents/Python$ ./script.sh Неверная последовательность команд. Неправильная последовательность команд. (локальный файл) (удаленный файл) Неверная последовательность команд. Неправильная последовательность команд. (локальный файл) (удаленный файл) - person maksaraswat; 24.04.2012

Если я не ошибаюсь, ncftp может принимать аргументы с подстановочными знаками:

ncftpput -u username -p password x.x.x.x archives /dir/*

Если он у вас еще не установлен, скорее всего, он доступен в стандартном репозитории для вашей ОС.

person Alex Howansky    schedule 24.04.2012
comment
lftp также может это сделать (у него есть команда mput для выполнения однократной установки нескольких файлов). - person Charles Duffy; 24.04.2012
comment
Кроме того, я не думаю, что ваша команда здесь использует режим ASCII, что отличает его от исходного сценария. - person Charles Duffy; 24.04.2012
comment
Конечно, справедливо ожидать, что ОП сделает немного работы... :) - person Alex Howansky; 24.04.2012

Во-первых, буквальный ответ, исправляющий ваш сценарий:

#!/bin/bash
# no reason to set variables that don't change inside the loop
host='x.x.x.x'
user='username'
password='password'
dir=archives
for i in /dir/*; do # no quotes if you want the wildcard to be expanded!
  if [ -f "$i" ]; then # need double quotes and whitespace here!
    file=$i
    ftp -n "$host" <<END_SCRIPT
quote USER $user
quote PASS $password
ascii
put $file $dir/$file
quit    
END_SCRIPT
  fi
done

Далее простой способ:

lftp -e 'mput -a *.i' -u "$user,$password" "ftp://$host/"

(да, lftp расширяет подстановочный знак внутри, а не ожидает, что это будет сделано внешней оболочкой).

person Charles Duffy    schedule 24.04.2012
comment
Спасибо всем за все предложения. Это действительно помогает. Я изменил свой сценарий на то, что предложил Чарльз, и когда я его выполняю, я получаю следующие ошибки: username@host:~/Documents/Python$ ./script.sh Неверная последовательность команд. Неправильная последовательность команд. (локальный файл) (удаленный файл) Неверная последовательность команд. Неправильная последовательность команд. (локальный файл) (удаленный файл) - person maksaraswat; 24.04.2012
comment
@user1354065 user1354065 Реализации FTP различаются, поэтому нельзя гарантировать, что один скрипт будет работать во всех них. Могу ли я предложить вам попробовать версию lftp? - person Charles Duffy; 24.04.2012
comment
@user1354065 user1354065 ... при этом в обзоре - переменная заглавная буква была непоследовательной; имя присваивалось $File, но $FILE разыменовывалось. Для переменных, не экспортируемых в среду, использование только прописных букв фактически противоречит соглашению, поэтому я обновил это, чтобы использовать все строчные буквы. - person Charles Duffy; 24.04.2012
comment
Спасибо, Чарльз! Я попытался выполнить скрипт так, как вы обновили выше, и он выдает следующее сообщение user@host:~/Documents/Python$ ./updated.sh Bad sequence of commands. Bad sequence of commands. Bad sequence of commands. Bad sequence of commands. - person maksaraswat; 24.04.2012
comment
Я также изменил сценарий на #!/bin/bash host='x.x.x.x' user='uname' passwd='passwd' dir='archives/sfg' lftp -e 'mput -a /localdir/*.*' -u "$user,$passwd" "sftp://$host/", и он зависает при следующем сообщении user@host:~/Documents/Python$ ./script.sh cd ok, cwd=/ ...abc.log' в 20 [Отправка данных]`, а затем мне нужно нажать CTRL + C, чтобы остановить его, так как он длится вечно. - person maksaraswat; 24.04.2012
comment
@maksaraswat эээ, sftp? это совершенно другой протокол, чем ftp; какой из них вы на самом деле хотите использовать? - person Charles Duffy; 24.04.2012
comment
Я могу войти на сайт только с помощью sftp (sftp uname@host), а не ftp (ftp uname@host). Итак, это sftp (плохо, что не ясно). - person maksaraswat; 24.04.2012
comment
@maksaraswat ... тогда весь этот вопрос ошибочен, поскольку он начинается с FTP, а не SFTP, как предпосылка. - person Charles Duffy; 24.04.2012

Прежде всего, мои извинения за то, что я не ясно выразился в вопросе. Моей фактической задачей было скопировать файл из локальной папки на сайт SFTP, а затем переместить файл в папку архива. Поскольку SFTP размещается у поставщика, я не могу использовать совместное использование ключей (ограничение поставщика. Кроме того, SCP потребует ввода пароля, если он используется в сценарии оболочки, поэтому я должен использовать SSHPASS. SSHPASS находится в репозитории Ubuntu, однако для CentOS необходимо установить отсюда

Текущий поток и Как запустить команду sftp с пароль от сценария Bash? помог мне лучше понять, как писать сценарий, и я поделюсь своим решением здесь:

#!/bin/bash
#!/usr/bin

for i in /dir/*; do 
 if [ -f "$i" ]; then 
file=$i
    export SSHPASS=password
    sshpass -e sftp -oBatchMode=no -b - [email protected] << !
    cd foldername/foldername
    put $file
 bye
 !
mv $file /somedir/test
fi
done

Спасибо всем за ответы! --Маянк

person maksaraswat    schedule 02.05.2012