SH скрипт копирования каталога
Добрый день!
Прошу помочь, пишу скрипт копирования целевой папки (внутри папки вложенная структура папок и файлов) в каталоги, список которых перечислен в текстовом файле (каждая строчка - новый каталог с указание пути относительно корня). Однако выполнение скрипта ни к чему не приводит..Помогите пожалуйста. Пример содержимого текстового файла: /home/centrin/domains/sites.ru/public_html/new/ /home/centrin/domains/home.ru/public_html/ Вот sh скрипт: #!/bin/sh if [ $# -ne 2 ] then echo "Параметры вызова: ([директория], [файл с адресами])" exit fi PATHS_FILE=$2 TARGET_DIR=$1 if !([ -d $TARGET_DIR ]) then echo "Заданная директория не найдена" exit fi if !([ -f $PATHS_FILE ]) then echo "Файл с адресами не найден" exit fi while read LINE; do if !([ -d $LINE ]) then mkdir $LINE fi echo "$TARGET_DIR/* to $LINE" cp -R $TARGET_DIR/* $path done < $PATHS_FILE echo "Done." |
|
ktotut, прошу прощения, но тут у Вас ошибка синтаксиса. Вместо
Цитата:
И еще, если позволите, два вопроса: 1. Учитываете ли Вы, что команда cp -R будет копировать далеко не все файлы? К примеру, не будут копироваться скрытые. Я бы, на Вашем месте воспользовался бы либо командой rsync (rsync -a -H -A -X --devices --specials -c -v --delete "$TARGET_DIR"/ "$LINE"), либо tar ( cd "$TARGET_DIR"; tar cf - . | (cd "$LINE" && tar xBf -). 2. Сценарий не будет работать правильно, если директория или имя файла содержат спецсимволы. К примеру, пробел. Решить эту проблему можно правильным использованием кавычек и установкой IFS в $"\n". Правда, файлы с символом перевода строки в имени всё равно не будут правильно обрабатываться, но, согласитесь, такие файлы встречаются редко (могу предложить вариант который будет правильно обрабатывать все файлы с корректными именами, даже содержащие переводы строки в имени, но, честно говоря, не вижу смысла - это не более, чем бесполезное упражнение в использовании команд оболочки, к тому же, его работоспособность далеко не очевидна с первого взгляда). |
Вложений: 1
К сожалению видимо я много чего не учитываю, однако пока ничего не помогает...
прикладываю скрин с консоли. сейчас текст скрипта выглядит так: #!/bin/sh if [ $# -ne 2 ] then echo "Параметры вызова: ([директория], [файл с адресами])" exit fi PATHS_FILE=$2 TARGET_DIR=$1 if !([ -d $TARGET_DIR ]) then echo "no directory" exit fi if !([ -f $PATHS_FILE ]) then echo "no file" exit fi while read LINE; do if ([ ! -d $LINE ]) then mkdir $LINE fi echo "$TARGET_DIR/* to $LINE" echo $TARGET_DIR echo $path cp -R $TARGET_DIR/* $path rsync -a -H -A -X --devices --specials -c -v --delete "$TARGET_DIR"/ "$LINE" done < $PATHS_FILE echo "Done." |
ktotut, запустите, пожалуйста Ваш сценарий командой:
Код:
bash -x script.sh administator site.txt &> script.log Покажите, если не сложно, результат выполнения "ls -l `which sh`" Я бы всё-таки рекомендовал Вам заменить в первой строчке #!/bin/sh на #!/bin/bash, сделать файл исполняемым (chmod a+x script.sh) и запускать его непосредственно, а не в виде параметра оболочки - это же неудобно. P.S. Строчки Цитата:
Цитата:
|
Цитата:
Цитата:
Цитата:
|
Цитата:
Цитата:
Понятно, что автору проще было вообще не ставить последнюю звездочку, а ограничиться указанием директории. |
Цитата:
Поэтому, даже из соображений портируемости сценария, я всегда предпочитаю указывать реальную оболочку. На любой настольной Linux-системе bash всегда будет установлен по умолчанию и его явное указание проблем создать не может. А если, к примеру, сценарий используется на какой-либо встроенной системе, это позволяет сразу выявить причину ошибки, без необходимости долго копаться, прежде чем будет установлено, что оператор "[" не был включен в данную версию busybox. Кроме того, это позволяет спокойно дорабатывать сценарий, включая в него специфичные для указанной оболочки возможности, не опасаясь того, что на другой машине вместо bash'а будет вызван dash (достаточно распространенная ситуация) и использованный в какой-то момент вместо "[" оператор "[[" будет интерпретирован как ошибка. |
Цитата:
Код:
kent@lazy /tmp % ls -aR copy* |
Цитата:
|
Вложений: 2
Всем добрый день!
Спасибо за активное участие в вопросе. Система у меня Linux version 2.6.32-5-amd64 (Debian 2.6.32-46) Прикладываю к сообщению log и скрипт (с внесенными изменениями) и вот еще результат команды: root@km35525:/home/centrin/domains/eduoren.ru/public_html# ls -l `which sh` lrwxrwxrwx 1 root root 4 Apr 11 2012 /bin/sh -> bash |
Цитата:
|
ktotut, у Вас в текущем каталоге отсутствует директория "administrator". Поэтому выполнение сценария и прерывается с выдачей Вашего же сообщения об отсутствии дректории. Думаю, Вы это и сами заметили.
Рекомендация: вводите абсолютный путь директории. P.S. Кстати, почему она называется "TARGET"? Скорее уж "SOURCE". Хотя на работу сценария это, ясен корень, никак не влияет. :wink: |
Теперь по поводу Вашего сценария. Вы всё-аки не до конца внесли те правки, о которых я Вам говорил.
Оператору "if" не нужны круглые скобки. Это не язык "С". Конечно, во многих случаях они не мешают, но раз уж мы с Вами начали учиться писать сценарии, давайте сразу осваивать хороший стиль программирования. :wink: Поэтому, убираем скобки в "if ([ ! -d $TARGET_DIR ])". Получается "if [ ! -d $TARGET_DIR ]". Выражение "if !([ ! -f $PATHS_FILE ])" ошибочно в принципе, поскольку содержит ссылку на историю команд (в сценарии она недоступна). Вполне вероятно, что эта команда может быть выполнена в сценарии (именно благодаря недоступности истории команд). Честно признаться, никогда не проверял. Но она совершенно точно не может быть исполнена в интерактивном режиме. Так что заменяем Ваш вариант на простой и понятный "if [ ! -f $PATHS_FILE ]". |
Вложений: 3
поправил. Директория находится на одном уровне со скриптом, просто допустил ошибку...
однако ничего не изменилось. Прикладываю файлы. |
ktotut, опубликуйте, пожалуйста, содержимое файла site.txt.
Как видите, попытка чтения из этого файла завершается неудачно и сценарий сразу выходит из цикла while. |
Вложений: 1
вот содержание файла site.txt
|
ktotut, у Вас файл site.txt не завершается переводом строки. Отсюда и ошибка - прчесть строку из файла нельзя, поскольку он содержит 0 строк (если не верите, можете проверить командой wc -l site.txt).
Кстати, заодно советовал бы добавить в команду mkdir опцию "-p". На всякий случай. |
Вложений: 3
Да, я тоже думал на это - увы нет..вот скрин и файлы.
|
ktotut, тогда выкладывайте очередной log.txt! :wink:
Предположение №1: rsync у Вас не установлен, а команда cp не проходит потому, что, несмотря на то, что Вам еще в самом первом сообщении рекомендовали это сделать (не я), Вы забыли заменить "$path" на "$LINE". Ведь переменная path у Вас нигде не определена, верно? |
Вложений: 1
Забыл лог прикрепить. )
|
ktotut, что и требовалось доказать.
Посмотрите этот файл и сами всё поймете. Или прочитайте моё предыдущее сообщение. ИЛИ установите rsync, ИЛИ замените везде $path на $LINE. |
Вложений: 1
Всё заработало...заменить $path на $LINE
Прикладываю на всякий случай конечный вариант скрипта. СПАСИБО ЗА ПОМОЩЬ! |
Цитата:
|
не заметил просто )
|
Время: 04:22. |
Время: 04:22.
© OSzone.net 2001-