2015-04-08 3 views
-2

У меня есть вопрос, связанный с моим скриптом оболочки bash. В принципе, мне нужно разработать скрипт, который копирует определенные файлы из одного каталога в другой. Звучит просто, но для меня это довольно сложная задача, и я надеюсь, что некоторые из вас могут мне помочь. Так скрипт должен работать так:Bash Shell Script для копирования файлов из источника в пункт назначения

SCRIPTNAME source_path Destination_path

1) 1-й проблемы - source_path не может существовать, и я должен повторить сообщение об ошибке.

2) Вторая проблема - путь назначения может не существовать, однако мне нужно создать некоторые или все каталоги, а затем скопировать файлы из источника. Иначе, если каталог существует, мне просто нужно скопировать.

Надеюсь, что это ясно и, надеюсь, кто-то может мне помочь!

+0

Является ли это для личного пользования? Поскольку это звучит как домашнее задание. Если его домашнее задание, что вы пробовали до сих пор? –

+0

Грег, ты прав, это для задания. У меня есть команда find для поиска определенных расширений и пропустить те, которые не нужны. – MrQuartz

ответ

0

Если вы хотите использовать команду find, попробуйте следующее:

find SRCPATH -exec mkdir -p DSTPATH/$(dirname "{}") \; -exec cp --parents "{}" DSTPATH \; 
  1. Каждый -exec флаг начинается блок кода оболочки для выполнения и \; завершает его. Получение нескольких команд в один -exec в прошлом оказалось проблематичным для меня, поэтому я включаю два, по одному для каждой задачи.

  2. {} является синтаксис find «S для переменной, которая указывает текущий путь find является пересекающий.

  3. Примечание: Флаг --parents на изменение Linux/GNU из cp, но не на всех версиях cp, поэтому ниже сценарий меньше зависят от платформы. Кроме того, ваш вопрос касался использования скрипта.

  4. Примечание: SRCPATH и DSTPATH представляют собой представляющие интерес пути. Если какое-либо имя каталога источника или назначения содержит пробелы, вы должны вложить их в " "


В качестве альтернативы вы можете сделать bash сценарий.

#!/bin/bash 
srcpath=$1 
dstpath=$2 
if [ ! -d "$srcpath" ]; then 
    echo "Source path: $srcpath doesn't exist" 
    exit 1 
fi 
mkdir -p "$dstpath" 
cp -r "$srcpath/*" "$dstpath" 
  1. -d флага в if заявления является флагом для проверки да/нет существования каталога. Вот некоторая информация о Баше file test operators и other bash comparison operators

  2. -p флага на mkdir рассказывает, чтобы заполнить недостающие компоненты путей по мере необходимости. Без -p, mkdir ожидает, что каждый компонент пути, за исключением конечного компонента пути, будет присутствовать или он потерпит неудачу.

  3. -r флаг на cp говорит cp рекурсивно скопировать все подкаталоги, а также файлы, указанные * к месту назначения, создавая эти подкаталоги по мере необходимости.

  4. Примечание: «" вокруг путей - это защита от ошибок, если какой-либо из компонентов пути содержит пробелы.

+0

Если вы выходите с отрицательным числом, статус возврата фактически покажет 255, я считаю, лучше использовать положительные числа при выходе из bash, чтобы получить ожидаемые коды возврата позже. Кроме того, при работе с mkdir -p не требуется тестирование для dir, я думаю, что вы можете просто сделать mkdir -p без каких-либо проблем, я бы заподозрил, что он всегда проверяет внутренний тест, так что вы удвоите работу. – GL2014

0

Установить переменные для аргументов один и два, источник и Dest соответственно ..

src_dir=$1 
dest_dir=$2 

Проверить, если каталог существует, если не выйти из

[[ -d $src_dir ]] || { echo "source dir not exist"; exit 1 ; } 

Создать все необходимые каталоги в пути

mkdir -p $dest_dir 
1

Посмотрите на это:

find SOURCEPATH -type f | while read fname 
do 
mkdir -p TARGETPATH/$(dirname "$fname") 
cp --parents $fname TARGETPATH 
done 

Просто substitude SourcePath и TargetPath и вы хорошо. find отображает ошибку, если SOURCEPATH не существует (1) и mkdir -p создаст каталоги.

+2

аккуратное использование 'find | в то время как читать' там; крутой рисунок. –

+0

@ Allaboutthatbase2 Сообщение содержит '" sourcepath ": нет такого файла или каталога'. Я думаю, это достаточно ясно, и я не думаю, что это стоит downvote :-(. – steffen

+0

@steffen Это классный трюк. Вы все еще немного усложнили его. Почему бы просто не использовать команду 'find' без всякой bash piping и чтение? Я обновил свой ответ с изменением. Другая проблема: флаг '--parents' на' cp' является Linux (или, возможно, POSIX или GNU) – clearlight

1

Этот скрипт создает всю структуру каталогов в $2 включая пустые папки из $1:

#!/bin/sh 
[ -z "$2" ] && { echo "Usage: $0 SOURCE DEST"; exit 1; } 
[ ! -d "$1" ] && { echo "'$1' does not exist or isn't a directory"; exit 1; } 
cp -r "$1" "$2" 

Если пустые каталоги должны быть пропущены, вам нужно больше логики; если rsync не доступен:

#!/bin/sh 
[ -z "$2" ] && { echo "Usage: $0 SOURCE DEST"; exit 1; } 
[ ! -d "$1" ] && { echo "'$1' does not exist or isn't a directory"; exit 1; } 
rsync -mr "$1" "$2" 

Объяснение:

  • Линия с -z проверяет, что второй аргумент не является пустым
  • Строка с ! -d проверяет, что каталог с первого аргумента существует
  • cp -r копии рекурсивно
  • rsync -mr копии рекурсивно но пропускает пустые каталоги
  • && и || широко используются для замены условных операторов (потому что они короткие)
Смежные вопросы