Уважаемые коллеги!Я пишу скрипт, который должен обрабатывать файлы согласно настройкам - перемещать/копировать их между разными источниками. Поскольку часть задач являются типовыми и повторяемыми, я принял решение использовать функции (http://www.opennet.me/docs/RUS/bash_scripting_guide/c12483.html). Структура скрипта вышла примерно такой - в начале идёт описание нескольких функций, в конце описан вызов их и их комбинаций в зависимости от входных параметров. Однако при запуске я вижу, что все функции начинают последовательно выполняться, параметры на их порядок не влияют. В какую сторону копать? Судя по документации, функции должны работать только после их вызова и уж никак не подряд по тексту скрипта сверху вниз!
Покажите код.
Код в студию (он довольно длинный, но ничего особенного нет, просто он не работает):Что характерно, если выкинуть всё, что связано с FTP - работает нормально...
#!/bin/bash
#
# (c), 2009, Larionov S.
#
# Скрипт для перемещения/копирования файлов между источниками разных типов.
#
# Порядок работы:
# 1. Запись параметров в переменные скрипта + проверка значений;
# 2. Если п.7 = new, то {формирование списка файлов + учёт списка уже захваченных в обработку файлов, параметр №8};
# 3. Формирование процедур обработки файлов;
# 4. Запуск процедур обработки файлов.
#ParameterCheck ()
{
if [ "$SrcType" != SMB ] && [ "$SrcType" != FTP ]
then
echo "Wrong SrcType parameter \"$SrcType\"! It should be equal to FTP or SMB only!"
exit $OTHER
fi# и т.д. для всех обязательных параметров
echo "Parameters are correct, continue"
}# 2.1. Формирование списка файлов. В зависимости от типа источника, методика будет разной!
CreateFileList ()
{
case $SrcType in
SMB )
eval "ls -1 /$SrcPath/$FileMask | sed s-/$SrcPath/-- > /$FileListFN"
;;FTP )
FTPName=`echo $SrcPath | sed s-\/.*--` # Разбор имени FTP в формате FTPName/FTPPath на составные части.
FTPPath=`echo $SrcPath | sed s-$FTPName\/--`
ftp -in "$FTPName" <<FTP_Communication
user $SrcFTPUser $SrcFTPPass
bin
cd $FTPPath
ls $FileMask /$FileListFN
quit
FTP_Communication
;;esac
}# 2.2. !!! Здесь должен быть код, собирающий список строк из файлов-списков из п.8 и убирающий названия файлов,
#+уже захваченных в обработку, из вновь создаваемого списка файлов для очередной обработки. Пока этого кода нет!!!# 3. Скрипты обработки файлов в разных системах:
# 3.1. SMB. Здесь всё просто - берём очередной файл из списка /$FileListFN и копируем его из пути $SrcPath в путь $TgtPath
# Cкрипт, позволяющий перемещать файлы по списку из SMB в SMB:
MoveFromSMBToSMB ()
{
echo "Preparing to move files from smb://$SrcPath to smb://$TgtPath"
for file in `cat /$FileListFN`; do
mv /$SrcPath/$file /$TgtPath/$file
done
echo "Files moved from smb://$SrcPath to smb://$TgtPath"
}# Cкрипт, позволяющий копировать файлы по списку из SMB в SMB:
CopyFromSMBToSMB ()
{
echo "Preparing to copy files from smb://$SrcPath to smb://$TgtPath"
for file in `cat /$FileListFN`; do
cp /$SrcPath/$file /$TgtPath/$file
done
echo "Files copied from smb://$SrcPath to smb://$TgtPath"
}# 3.2. FTP. По-хорошему, надо проверять ошибку копирования/перемещения файлов и только после этого продолжать.
# Cкрипт, позволяющий перемещать файлы по списку из FTP в SMB:
MoveFromFTPToSMB ()
{
FTPName=`echo "$SrcPath" | sed s-\/.*--`
FTPPath=`echo "$SrcPath" | sed s-$FTPName\/--`
if [ $1 ]
then
TgtPath=$1
fi
echo "Tgt Path = /$TgtPath"
Files=eval awk '/\*/{print "";next}{printf("%s ", $0)}END{print ""}' /$FileListFN # Преобразование файла-списка из многострочного в значения, разделённые пробелами для mget, mput и mdelete:
echo "Preparing to move files from ftp://$SrcPath to smb://$TgtPath"
ftp -in $FTPName <<MoveFromFTPToSMB
user $SrcFTPUser $SrcFTPPass
bin
lcd /$TgtPath
mget $Files
mdelete $Files
quit
MoveFromFTPToSMB
echo "Files moved from ftp://$SrcPath to smb://$TgtPath"
}# Cкрипт, позволяющий копировать файлы по списку из FTP в SMB:
CopyFromFTPToSMB ()
{
FTPName=`echo "$SrcPath" | sed s-\/.*--`
FTPPath=`echo "$SrcPath" | sed s-$FTPName\/--`
if [ $1 ]
then
TgtPath=$1
fi
echo "Tgt Path = /$TgtPath"
Files=eval awk '/\*/{print "";next}{printf("%s ", $0)}END{print ""}' /$FileListFN # Преобразование файла-списка из многострочного в значения, разделённые пробелами для mget, mput и mdelete:
echo "Preparing to copy files from ftp://$SrcPath to smb://$TgtPath"
ftp -in $FTPName <<CopyFromFTPToSMB
user $SrcFTPUser $SrcFTPPass
bin
lcd /$TgtPath
mget $Filesquit
CopyFromFTPToSMB
echo "Files copied from ftp://$SrcPath to smb://$TgtPath"
}# Cкрипт, позволяющий перемещать файлы по списку из SMB в FTP:
MoveFromSMBToFTP ()
{
FTPName=`echo "$TgtPath" | sed s-\/.*--`
FTPPath=`echo "$TgtPath" | sed s-$FTPName\/--`
if [ $1 ]
then
SrcPath=$1
fi
echo "Src Path = /$SrcPath"
Files=eval awk '/\*/{print "";next}{printf("%s ", $0)}END{print ""}' /$FileListFN # Преобразование файла-списка из многострочного в значения, разделённые пробелами для mget, mput и mdelete:
echo "Preparing to move files from smb://$SrcPath to ftp://$TgtPath"
ftp -in $FTPName <<MoveFromSMBToFTP
user $TgtFTPUser $TgtFTPPass
bin
lcd /$SrcPath
mput $Files
quit
MoveFromSMBToFTP
for file in `cat /$FileListFN`; do
rm /$SrcPath/$file
done
echo "Files moved from smb://$SrcPath to ftp://$TgtPath"
}# Cкрипт, позволяющий копировать файлы по списку из SMB в FTP:
CopyFromSMBToFTP ()
{
FTPName=`echo "$TgtPath" | sed s-\/.*--`
FTPPath=`echo "$TgtPath" | sed s-$FTPName\/--`
if [ $1 ]
then
SrcPath=$1
fi
echo "Src Path = /$SrcPath"
Files=eval awk '/\*/{print "";next}{printf("%s ", $0)}END{print ""}' /$FileListFN # Преобразование файла-списка из многострочного в значения, разделённые пробелами для mget, mput и mdelete:
echo "Preparing to copy files from smb://$SrcPath to ftp://$TgtPath"
ftp -in $FTPName <<CopyFromSMBToFTP
user $TgtFTPUser $TgtFTPPass
bin
lcd /$SrcPath
mput $Files
quit
CopyFromSMBToFTP
echo "Files copied from smb://$SrcPath to ftp://$TgtPath"
}# 3.4. Если удастся организовать FXP, можно будет гонять данные непосредственно между
# FTP-серверами (см. http://www.opennet.me/base/net/ftp2ftp.txt.html).
# Пока предполагается реализовать download с FTP-сервера-источника во временную
# папку $TmpPath, затем upload из временной папки $TmpPath на FTP-сервер-приёмник.
#
# 4.# 1.2. Несколько рабочих констант.
SUCCESS=0
OTHER=65
TmpPath=tmp/FO# Параметры запуска :
# ---------------------------------------------------- Parameter file begin ----------------------------------------------------
FileMask="*.xml" # | grep 'Default'" # 1. Маска файла (обязательный);
SrcType="SMB" # 2. Тип источника. Возможные варианты - SMB, FTP (обязательный);
TgtType="SMB" # 3. Тип приёмника. Возможные варианты - SMB, FTP (обязательный);
SrcPath="usr/ScriptSL/USSD/in" # 4. Путь-источник (обязательный);
TgtPath="usr/ScriptSL/USSD/work" # 5. Путь-приёмник (обязательный);
ActType="copy" # 6. Метод копирования. Возможные варианты - copy, move (обязательный);
FileListUsage="new" # 7. Список файлов - создавать новый (new) или использовать имеющийся (old)? (обязательный);
FileListFN="usr/ScriptSL/USSD/XML_25874.lst" # 8. Полное имя (с путём) списка файлов (нового или имеющегося) (обязательный);
SrcFTPUser="FTPUser" # 10. Логин FTP-сервера источника;
SrcFTPPass="1" # 11. Пароль FTP-сервера источника;
TgtFTPUser="" # 12. Логин FTP-сервера приёмника;
TgtFTPPass="" # 13. Пароль FTP-сервера приёмника.
# ----------------------------------------------------- Parameter file end -----------------------------------------------------# 1.3. Проверка значений параметров.
ParameterCheck
if [ "$FileListUsage" = new ]
then
echo "Listing of folder $SrcType://$SrcPath"
CreateFileList
echo "Listing created, continue"
fiif [ "$SrcType" = SMB ] && [ "$TgtType" = FTP ]
if [ "$ActType" = copy ]
then
echo "Copy From SMB To FTP started..."
CopyFromSMBToFTP
echo "Copy From SMB To FTP finished..."
elif [ "$ActType" = move ]
then
echo "Move From SMB To FTP started..."
MoveFromSMBToFTP
echo "Move From SMB To FTP finished..."
fi
then :
fiif [ "$SrcType" = FTP ] && [ "$TgtType" = SMB ]
if [ "$ActType" = copy ]
then
echo "Copy From FTP To SMB started..."
CopyFromFTPToSMB
echo "Copy From FTP To SMB finished..."
elif [ "$ActType" = move ]
then
echo "Move From FTP To SMB started..."
MoveFromFTPToSMB
echo "Move From FTP To SMB finished..."
fi
then :
fiif [ "$SrcType" = FTP ] && [ "$TgtType" = FTP ]
if [ "$ActType" = copy ]
then
echo "Copy From FTP To FTP started..."
CopyFromFTPToSMB $TmpPath
CopyFromSMBToFTP $TmpPath
echo "Copy From FTP To FTP finished..."
elif [ "$ActType" = move ]
then
echo "Move From FTP To FTP started..."
MoveFromFTPToSMB $TmpPath
MoveFromSMBToFTP $TmpPath
echo "Move From FTP To FTP finished..."
fi
then :
fiif [ "$SrcType" = SMB ] && [ "$TgtType" = SMB ]
if [ "$ActType" = copy ]
then
echo "Copy From SMB To SMB started..."
CopyFromSMBToSMB
echo "Copy From SMB To SMB finished..."
elif [ "$ActType" = move ]
then
echo "Move From SMB To SMB started..."
MoveFromSMBToSMB
echo "Move From SMB To SMB finished..."
fi
then :
fiexit $SUCCESS
При запуске скрипта терминал показывает вывод всех echo с начала скрипта + пытается выполнить операции перемещения/копирования/доступа к FTP.
> if [ "$SrcType" = FTP ] && [ "$TgtType" = SMB ]
>
> if [ "$ActType" = copy ]
> ...
> elif [ "$ActType" = move ]
> then
> ...
> fi
> then :
> fiВесь код смотреть, а уж тем более запускать лень, но это место мне не
нравится. Ты зачем-то вписал вложенный if не в then...fi, а сразу после
условий первого. И двоеточие непонятно зачем светится.
Хм, это я накосячил, такая конструкция неправильна. Поправил, логика вернулась! Спасибо!
>[оверквотинг удален]
>
>Я пишу скрипт, который должен обрабатывать файлы согласно настройкам - перемещать/копировать их
>между разными источниками. Поскольку часть задач являются типовыми и повторяемыми, я
>принял решение использовать функции (http://www.opennet.me/docs/RUS/bash_scripting_guide/c12483.html). Структура скрипта вышла примерно такой -
>в начале идёт описание нескольких функций, в конце описан вызов их
>и их комбинаций в зависимости от входных параметров. Однако при запуске
>я вижу, что все функции начинают последовательно выполняться, параметры на их
>порядок не влияют. В какую сторону копать? Судя по документации, функции
>должны работать только после их вызова и уж никак не подряд
>по тексту скрипта сверху вниз!это к телепатам...
>[оверквотинг удален]
>>между разными источниками. Поскольку часть задач являются типовыми и повторяемыми, я
>>принял решение использовать функции (http://www.opennet.me/docs/RUS/bash_scripting_guide/c12483.html). Структура скрипта вышла примерно такой -
>>в начале идёт описание нескольких функций, в конце описан вызов их
>>и их комбинаций в зависимости от входных параметров. Однако при запуске
>>я вижу, что все функции начинают последовательно выполняться, параметры на их
>>порядок не влияют. В какую сторону копать? Судя по документации, функции
>>должны работать только после их вызова и уж никак не подряд
>>по тексту скрипта сверху вниз!
>
>это к телепатам...Пардон, выложил код в предыдущем ответе.