URL: https://www.opennet.ru/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 8415
[ Назад ]

Исходное сообщение
"Функции в Shell"

Отправлено SLario , 31-Авг-09 15:57 
Уважаемые коллеги!

Я пишу скрипт, который должен обрабатывать файлы согласно настройкам - перемещать/копировать их между разными источниками. Поскольку часть задач являются типовыми и повторяемыми, я принял решение использовать функции (https://www.opennet.ru/docs/RUS/bash_scripting_guide/c12483.html). Структура скрипта вышла примерно такой - в начале идёт описание нескольких функций, в конце описан вызов их и их комбинаций в зависимости от входных параметров. Однако при запуске я вижу, что все функции начинают последовательно выполняться, параметры на их порядок не влияют. В какую сторону копать? Судя по документации, функции должны работать только после их вызова и уж никак не подряд по тексту скрипта сверху вниз!


Содержание

Сообщения в этом обсуждении
"Функции в Shell"
Отправлено phpcoder , 31-Авг-09 15:58 
Покажите код.



"Функции в Shell"
Отправлено SLario , 31-Авг-09 16:42 
Код в студию (он довольно длинный, но ничего особенного нет, просто он не работает):

Что характерно, если выкинуть всё, что связано с 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 $Files

quit
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-серверами (см. https://www.opennet.ru/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"
fi

if [ "$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 :
fi

if [ "$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 :
fi

if [ "$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 :
fi

if [ "$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 :
fi

exit $SUCCESS


"Функции в Shell"
Отправлено SLario , 31-Авг-09 17:04 
При запуске скрипта терминал показывает вывод всех echo с начала скрипта + пытается выполнить операции перемещения/копирования/доступа к FTP.

"Функции в Shell"
Отправлено gaa , 31-Авг-09 19:45 
> if [ "$SrcType" = FTP ] && [ "$TgtType" = SMB ]
>
>    if [ "$ActType" = copy ]
>    ...
>    elif [ "$ActType" = move ]
>    then
>    ...
>    fi
> then :
> fi

Весь код смотреть, а уж тем более запускать лень, но это место мне не
нравится. Ты зачем-то вписал вложенный if не в then...fi, а сразу после
условий первого. И двоеточие непонятно зачем светится.


"Функции в Shell"
Отправлено SLario , 01-Сен-09 10:12 
Хм, это я накосячил, такая конструкция неправильна. Поправил, логика вернулась! Спасибо!


"Функции в Shell"
Отправлено Pahanivo , 31-Авг-09 16:34 
>[оверквотинг удален]
>
>Я пишу скрипт, который должен обрабатывать файлы согласно настройкам - перемещать/копировать их
>между разными источниками. Поскольку часть задач являются типовыми и повторяемыми, я
>принял решение использовать функции (https://www.opennet.ru/docs/RUS/bash_scripting_guide/c12483.html). Структура скрипта вышла примерно такой -
>в начале идёт описание нескольких функций, в конце описан вызов их
>и их комбинаций в зависимости от входных параметров. Однако при запуске
>я вижу, что все функции начинают последовательно выполняться, параметры на их
>порядок не влияют. В какую сторону копать? Судя по документации, функции
>должны работать только после их вызова и уж никак не подряд
>по тексту скрипта сверху вниз!

это к телепатам...


"Функции в Shell"
Отправлено SLario , 31-Авг-09 16:43 
>[оверквотинг удален]
>>между разными источниками. Поскольку часть задач являются типовыми и повторяемыми, я
>>принял решение использовать функции (https://www.opennet.ru/docs/RUS/bash_scripting_guide/c12483.html). Структура скрипта вышла примерно такой -
>>в начале идёт описание нескольких функций, в конце описан вызов их
>>и их комбинаций в зависимости от входных параметров. Однако при запуске
>>я вижу, что все функции начинают последовательно выполняться, параметры на их
>>порядок не влияют. В какую сторону копать? Судя по документации, функции
>>должны работать только после их вызова и уж никак не подряд
>>по тексту скрипта сверху вниз!
>
>это к телепатам...

Пардон, выложил код в предыдущем ответе.