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

Исходное сообщение
"Копирование с помощью dd каталогов"

Отправлено Mazik , 15-Дек-09 11:29 
Возникла проблемка:
имеются два каталога /src и /dest

В них содержатся поткаталоги в которых соответственно есть файлы, их очень много.
Задача значит такая скопировать рекурсивно из каталога /src в каталог /dest.
можно конечно писать файлик типа:
dd if=/src/dir1/file1.dbf of=/src/dir1/file1.dbf bs=50M

Но для тысяч файлов это не практично и ошибиться можно, почему именно dd, потому что отключено кеширование на дисках.

Вопрос: куда копать и как быть? Кто может сталкивался?  


Содержание

Сообщения в этом обсуждении
"Копирование с помощью dd каталогов"
Отправлено Michael , 15-Дек-09 12:13 
>[оверквотинг удален]
>В них содержатся поткаталоги в которых соответственно есть файлы, их очень много.
>
>Задача значит такая скопировать рекурсивно из каталога /src в каталог /dest.
>можно конечно писать файлик типа:
>dd if=/src/dir1/file1.dbf of=/src/dir1/file1.dbf bs=50M
>
>Но для тысяч файлов это не практично и ошибиться можно, почему именно
>dd, потому что отключено кеширование на дисках.
>
>Вопрос: куда копать и как быть? Кто может сталкивался?

pax(1)


"Копирование с помощью dd каталогов"
Отправлено Mazik , 15-Дек-09 12:45 
>pax(1)

Спасибо :)

Щас попробую этого зверя


"Копирование с помощью dd каталогов"
Отправлено Mazik , 15-Дек-09 14:40 
>>pax(1)
>
>Спасибо :)
>
>Щас попробую этого зверя

Не pax не подходит, скорость копирования сравнима с cp - нужно большую которая дает dd ^(



"Копирование с помощью dd каталогов"
Отправлено Slavaz , 15-Дек-09 15:10 
>Не pax не подходит, скорость копирования сравнима с cp - нужно большую
>которая дает dd ^(

rsync не подойдёт?



"Копирование с помощью dd каталогов"
Отправлено Mazik , 16-Дек-09 05:50 
>>Не pax не подходит, скорость копирования сравнима с cp - нужно большую
>>которая дает dd ^(
>
>rsync не подойдёт?

Промышленный сервер с AIX там нет ни rsync ни gcc и ставить нельзя их, так что нужно решать вопрос стандартными средствами.


"Копирование с помощью dd каталогов"
Отправлено Michael , 15-Дек-09 15:36 
>>>pax(1)
>>
>>Спасибо :)
>>
>>Щас попробую этого зверя
>
>Не pax не подходит, скорость копирования сравнима с cp - нужно большую
>которая дает dd ^(

тогда остается рекурсивно обходить каталоги и для каждого файла вызывать дд


"Копирование с помощью dd каталогов"
Отправлено jd , 15-Дек-09 16:16 
>тогда остается рекурсивно обходить каталоги и для каждого файла вызывать дд

... что в общем-то несложно, имея под рукой find, dirname, basename и т.д.


"Копирование с помощью dd каталогов"
Отправлено vg , 15-Дек-09 18:02 
>>тогда остается рекурсивно обходить каталоги и для каждого файла вызывать дд
>
>... что в общем-то несложно, имея под рукой find, dirname, basename и
>т.д.

и получим тот же ср или rsync :)


"Копирование с помощью dd каталогов"
Отправлено Mazik , 16-Дек-09 06:01 
>>>тогда остается рекурсивно обходить каталоги и для каждого файла вызывать дд
>>
>>... что в общем-то несложно, имея под рукой find, dirname, basename и
>>т.д.
>
>и получим тот же ср или rsync :)

Это понятно: dd + find, dirname, basename + цикл
вот например

IF=(`source_dir`)
OF=(`destination_dir`)

LIMIT=`find $OF -type f | wc -l ;` #$LIMIT

for ((a=0; a <= LIMIT ; a++))  
do
  echo if="${IF[a]}" of="${OF[a]}" count=10000 bs=10M
  # а вот с dd здесь проблемма как его сюда правильно затолкать или есть другие варианты,
  # я уже голову сломал как подставить в ДД 2 переменные
  done



"Копирование с помощью dd каталогов"
Отправлено Arpo , 16-Дек-09 08:11 
>[оверквотинг удален]
>LIMIT=`find $OF -type f | wc -l ;` #$LIMIT
>
>for ((a=0; a <= LIMIT ; a++))
>do
>  echo if="${IF[a]}" of="${OF[a]}" count=10000 bs=10M
>  # а вот с dd здесь проблемма как его сюда
>правильно затолкать или есть другие варианты,
>  # я уже голову сломал как подставить в ДД 2
>переменные
>  done

А while не прокатит?

Что то типа

IF=(`source_dir`)
OF=(`destination_dir`)

find $OF -type f|while read file
do
     dd if="$IF/$file" of="$OF/$file" count=10000 bs=10M
done

К сожалению проверить на данный момент негде...


"Копирование с помощью dd каталогов"
Отправлено jd , 16-Дек-09 12:45 
Да господь с вами, что вы такое пишете!? Какой ещё цикл, какие списки (и вообще, что означает конструкция `source_dir`?)?  Опция -exec у find'а - вот, что здесь нужно. И какой ещё count=10000? Что, файлы длиннее 100G недостойны быть скопированы целиком? Не нужно вообще никакой предел указывать.

"Копирование с помощью dd каталогов"
Отправлено Mazik , 16-Дек-09 13:56 
>Да господь с вами, что вы такое пишете!? Какой ещё цикл, какие
>списки (и вообще, что означает конструкция `source_dir`?)?  Опция -exec у
>find'а - вот, что здесь нужно. И какой ещё count=10000? Что,
>файлы длиннее 100G недостойны быть скопированы целиком? Не нужно вообще никакой
>предел указывать.

count=10000 и source_dir это просто пример.
Хотел бы я посмотреть как ты вставишь find .. exec`ом параметры в dd if=?? of=?? :):)



"Копирование с помощью dd каталогов"
Отправлено jd , 16-Дек-09 15:13 
>Хотел бы я посмотреть как ты вставишь find .. exec`ом параметры в
>dd if=?? of=?? :):)

Ну так и быть, смотрите:


#!/bin/sh

if [ "$1" = '' -o "$2" = '' ]; then
  echo "Usage: $0 src_dir dst_dir" >&2
  exit 1
fi

cd $2
cd -
DST=$OLDPWD
cd $1

find -type d -exec mkdir -p $DST/\{\} \;
find -type f -exec dd bs=10M if=\{\} of=$DST/\{\} \;


Это так, за пару минут сляпал. Дальше уж сами как-нибудь...



"Копирование с помощью dd каталогов"
Отправлено Mazik , 17-Дек-09 08:33 
>[оверквотинг удален]
>
>cd $2
>cd -
>DST=$OLDPWD
>cd $1
>
>find -type d -exec mkdir -p $DST/\{\} \;
>find -type f -exec dd bs=10M if=\{\} of=$DST/\{\} \;
>

>Это так, за пару минут сляпал. Дальше уж сами как-нибудь...

Спасибо :) Надо попробовать.


"Копирование с помощью dd каталогов"
Отправлено ACCA , 16-Дек-09 07:20 
>Задача значит такая скопировать рекурсивно из каталога /src в каталог /dest.
>можно конечно писать файлик типа:
>dd if=/src/dir1/file1.dbf of=/src/dir1/file1.dbf bs=50M

find ... | cpio -p -C 52428800 ...


"Копирование с помощью dd каталогов"
Отправлено Mazik , 16-Дек-09 08:23 
>>Задача значит такая скопировать рекурсивно из каталога /src в каталог /dest.
>>можно конечно писать файлик типа:
>>dd if=/src/dir1/file1.dbf of=/src/dir1/file1.dbf bs=50M
>
>find ... | cpio -p -C 52428800 ...

За что не люблю AIX так это за то что все у нею через жо... :(
В AIX не работает связка типа cpio -p -C 52428800 т.е. размер блока можно указывать тока с
-i... C2 и только для создания архива, в пингвинах такой проблемы нету и в солярке насколько я помню тоже :(


"Копирование с помощью dd каталогов"
Отправлено ACCA , 16-Дек-09 10:02 
>[оверквотинг удален]
>>>можно конечно писать файлик типа:
>>>dd if=/src/dir1/file1.dbf of=/src/dir1/file1.dbf bs=50M
>>
>>find ... | cpio -p -C 52428800 ...
>
>За что не люблю AIX так это за то что все у
>нею через жо... :(
>В AIX не работает связка типа cpio -p -C 52428800 т.е. размер
>блока можно указывать тока с
>-i... C2 и только для создания архива, в пингвинах такой проблемы нету

Не сильно хуже будет cpio -i -C ... | cpio -o. Основная проблема - полёты головы между чтением и записью. Для борьбы с нею достаточно создать большой буфер на любой стороне.


"Копирование с помощью dd каталогов"
Отправлено Nas_tradamus , 17-Дек-09 13:29 
А такой вариант не подойдет?

tar -cvf - -C /src . | tar -xpvf - -C /dest/

Недавно копировал таким способом 25 гигов - заняло примерно 20 минут SAS HDD -> SATA HDD.



"Копирование с помощью dd каталогов"
Отправлено Mazik , 17-Дек-09 13:33 
>А такой вариант не подойдет?
>
>tar -cvf - -C /src . | tar -xpvf - -C /dest/
>
>
>Недавно копировал таким способом 25 гигов - заняло примерно 20 минут SAS HDD -> SATA HDD.

Нет слишком медленно, когда нужно копировать терабайты данных.



"Копирование с помощью dd каталогов"
Отправлено Andrey Mitrofanov , 17-Дек-09 14:01 
>А такой вариант не подойдет?
>tar -cvf - -C /src . | tar -xpvf - -C /dest/

А добавление "буфера" к нему (именно с помощью dd) как нистранно:

tar -cvf - -C /src . |dd bs=10M | tar -xpvf - -C /dest/

Вот здесь- http:/openforum/vsluhforumID1/82553.html#4 про то же с cpio+find, соответственно, варианты с буфером примерно так---

$ cd $FROM_DIR; find |cpio -oa --format=newc |dd bs=50K |ssh $NEWHOST "cd $TO_DIR; dd bs=1M | cpio -idmu"

$ cd $FROM_DIR; find |cpio -oa --format=newc |dd bs=10M | cpio -idmu $TO_DIR

То есть заворачиваем что надо в архив (tar/cpio/...), архив - в конвейер, конвейер читать-писать кусками такого-то размера(=буферизовать), "на той стороне" - распаковать из архива в указанную директорию.

Хотя идея диска и без буферизации -- пуга-а-ает. %)


"Копирование с помощью dd каталогов"
Отправлено Mazik , 17-Дек-09 14:24 

>
>Хотя идея диска и без буферизации -- пуга-а-ает. %)

Орокля крутится там, в аиксе на тех дисках нужно отключать буферизацию в системе, а орокля свою систему использует


"Копирование с помощью dd каталогов"
Отправлено Andrey Mitrofanov , 17-Дек-09 14:32 
>Орокля
>в аиксе
>отключать буферизацию

Ну, я так и подумал, что задача так же крива, как и её решение. $))


"Копирование с помощью dd каталогов"
Отправлено Mazik , 17-Дек-09 14:26 
>[оверквотинг удален]
>В них содержатся поткаталоги в которых соответственно есть файлы, их очень много.
>
>Задача значит такая скопировать рекурсивно из каталога /src в каталог /dest.
>можно конечно писать файлик типа:
>dd if=/src/dir1/file1.dbf of=/src/dir1/file1.dbf bs=50M
>
>Но для тысяч файлов это не практично и ошибиться можно, почему именно
>dd, потому что отключено кеширование на дисках.
>
>Вопрос: куда копать и как быть? Кто может сталкивался?

Все народ решил я проблему с dd ураа, если хотите могу выложить :)


"Копирование с помощью dd каталогов"
Отправлено Mazik , 17-Дек-09 14:42 
>[оверквотинг удален]
>>можно конечно писать файлик типа:
>>dd if=/src/dir1/file1.dbf of=/src/dir1/file1.dbf bs=50M
>>
>>Но для тысяч файлов это не практично и ошибиться можно, почему именно
>>dd, потому что отключено кеширование на дисках.
>>
>>Вопрос: куда копать и как быть? Кто может сталкивался?
>
>Все народ решил я проблему с dd ураа, если хотите могу выложить
>:)

Вот скриптец, народ тока сильно не пинайте приму любые пожелания :)

ddcopy.sh

#!/bin/bash
#
# The given script has been created for simplification of process of  
# recursive copying of files and directories by means of utility
# Dataset definition dd.  
#
# The author Dmitriy V. Mazitov 2009
# v. 1
#
# Usage order the following:
#
# ddcopy.sh /source_dir /destination_dir bs cf cdd rm
#
# Explanations:
#
# bs - a block size in mbytes (the Example: we enter number 50)
#
# cf - generation of a file of a script (the Example: we enter y or n)
#
# cdd - the consent to copying (the Example: we enter y or n)
#
# rm - removal of folders and files in a destination directory
# (the Example: we enter y or n)
#
# Example:
#
# ddcopy.sh /home/bob/films /home/share/video 50 y y n
#
# The file a script will be is in a home folder of the user from which  
# name has been started ddcopy.sh
#
# It is possible to create a file a script for its studying and hand-held
# performance.
#
# G U A R A N T E E S
#
# A N Y
#
# dmitriy@ituniservice.ru
#
#
clear
cd
rm -f -v start_dd_copy.sh
#=======================================

src=$1
dest=$2
block_size=$3
create_files=$4
copy_dd=$5
rm_files_and_dir=$6


l=`find $src -type f | wc -l`
let "l-=1"
LIMIT=$l


files () {
        find $src -follow -type f | cat | while read line; do echo "${line##*/}"; done
    }

rm_files_dest () {
        find $dest -follow -type f | cat | while read line; do echo "${line##*/}"; rm "${line[@]}"; done
    }

input_source () {
                find $src -follow -type f | while read string
            do    
        echo $string
    done
}

search () {
        LIMIT_S=(`input_source | wc -l`)    
        v0=(`input_source`)
        for ((a=0; a <= LIMIT_S ; a++))
        do
    echo "${v0[a]/#$src/$dest}"
done
}

dd_out_screen () {
                IF=(`input_source`)
                OF=(`search`)
                BLS=$block_size
                for ((a=0, b=0; a <= LIMIT, b <= LIMIT ; a++, b++))  
            do
    echo dd if="${IF[a]}" of="${OF[b]}" bs="${BLS[@]}"M
  done                      
}

dd_dir_for_copy() {
                    IF=(`input_source`)
                OF=(`search`)
                BLS=$block_size
                for ((a=0; a <= LIMIT ; a++))  
            do
        dirname "${OF[a]}"
  done                      
}

create_dir () {
                    DIR=(`dd_dir_for_copy`)
                    LIMIT_S=(`input_source | wc -l`)
                for ((a=0; a <= LIMIT_S ; a++))  
            do
        mkdir -p "${DIR[a]}"
  done
}

dd_copy () {
            IF=(`input_source`)
                OF=(`search`)
                    BLS=$block_size
                    l1=`input_source | wc -l`
                    let "l1-=1"
                LIMIT_S=$l1
                #LIMIT_S=(`input_source | wc -l`)
                for ((a=0, b=0; a <= LIMIT_S, b <= LIMIT_S ; a++, b++))  
            do
        dd if="${IF[a]}" of="${OF[b]}" bs="${BLS[@]}"M
  done                      
}


check_all () {
if [ "$src" = '' -o "$dest" = '' -o "$block_size" = '' -o "$create_files" = '' -o "$copy_dd" = '' -o "$rm_files_and_dir" = '' ];
    then
        echo "Error!"
        echo "Usage: script src_dir dest_dir" >&2
        echo "Example: Enter the directory a source and destination:" >&2
        echo "/foo/dir1 /home/user/catalog1 10 y y y" >&2    
        echo "Enter 'ddcopy.sh ls --help or -h' for reception of more detailed description." >&2
    exit 1
fi
}

helps () {
  clear
echo "The given script has been created for simplification of process of" >&2
echo "recursive copying of files and directories by means of utility" >&2
echo "Dataset definition "dd"." >&2
echo
echo "The author Dmitriy V. Mazitov 2009" >&2
echo "v. 1" >&2
echo
echo "Usage order the following:" >&2
echo
echo "ddcopy.sh /source_dir /destination_dir bs cf cdd rm" >&2
echo
echo "Explanations:" >&2
echo
echo "bs - a block size in mbytes (the Example: we enter number 50)" >&2
echo
echo "cf - generation of a file of a script (the Example: we enter y or n)" >&2
echo
echo "cdd - the consent to copying (the Example: we enter y or n)" >&2
echo
echo "rm - removal of folders and files in a destination directory" >&2
echo "(the Example: we enter y or n)" >&2
echo
echo "Example:" >&2
echo
echo "ddcopy.sh /home/bob/films /home/share/video 50 y y n" >&2
echo
echo "The file a script will be is in a home folder of the user from which " >&2
echo "name has been started ddcopy.sh" >&2
echo
echo "It is possible to create a file a script for its studying and hand-held" >&2
echo "performance." >&2
echo
echo "G U A R A N T E E S" >&2
echo
echo "A N Y" >&2
echo
echo "dmitriy@ituniservice.ru" >&2
  
}
helps_check () {
if [ "$src" = '--help' -o "$src" = '-h' ]
then
            echo
            helps
        else
    echo
    check_all
  #exit 0
fi
}


validation_check () {
echo $src | grep '/*/' > /dev/null
if [ $? -ne 0 ]; then echo "The sources dir is incorrectly entered!"
helps_check
exit;
fi

echo $dest | grep '/*/' > /dev/null  
if [ $? -ne 0 ]; then
echo "The destination dir is incorrectly entered!"
sleep 3
helps
exit;
fi
  
if (("$block_size" >= 1))
        then
            echo
        else
    echo "The block size is incorrectly entered!"
    sleep 3
    helps
  exit 0
fi

if [ "$create_files" = "y" -o "$create_files" = "n" ]
    then
            echo
            else
    echo "The create command files is incorrectly entered!"
    sleep 3
    helps
  exit 0
fi

if [ "$copy_dd" = 'y' -o "$copy_dd" = 'n' ]
then
            echo
        else
    echo "The copy on dd command is incorrectly entered!"
    sleep 3
    helps
  exit 0
fi

if [ "$rm_files_and_dir" = 'y' -o "$rm_files_and_dir" = 'n' ]
then
            echo
        else
    echo "The remove files and dirs command is incorrectly entered!"
    sleep 3
    helps
  exit 0
fi
}

run () {
if [ "$create_files" = "y" ]
    then
        echo
            cd
            dd_out_screen  >> start_dd_copy.sh
            chmod 777 start_dd_copy.sh
        echo
        else
    echo
  fi

if [ "$rm_files_and_dir" = 'y' ]
    then
        echo
        rm_files_dest
        else
    echo
  fi

if [ "$copy_dd" = 'y' ]
then
        echo
        create_dir
        dd_copy
        RETCODE=$?
        if [ $RETCODE -ne 0 ]; then
        echo "Err code="$RETCODE""
        else
        echo "Good code="$RETCODE""
        fi
        else
    echo
  fi
}

if [ "$src" = '' ]
then
            echo
            helps_check
        else
    echo
    validation_check
    helps_check
fi

run


"Копирование с помощью dd каталогов"
Отправлено jd , 17-Дек-09 15:50 
Мама дорогая... Вам зарплату за строчки что-ли платят?

вот это очень порадовало (:

input_source () {
                find $src -follow -type f | while read string
            do    
        echo $string
    done
}


"Копирование с помощью dd каталогов"
Отправлено Mazik , 17-Дек-09 18:19 
>[оверквотинг удален]
>
>вот это очень порадовало (:
input_source () { 
>            
>    find $src -follow -type f | while
>read string
>            
>do
>        echo $string
>    done
>}

Согласен код не самый оптимальный но я и не шелловский  гуру
главное работает :)


"Копирование с помощью dd каталогов"
Отправлено Mazik , 21-Дек-09 16:43 
Вот новый скриптец, доработанный маленький и с прогресс баром для копирования с помощью dd как каталогов так отдельных файлов

duda.sh

#!/bin/bash
clear
ARGS=3
E_BADARGS=65
cd .
if [ $# -ne "$ARGS" ]
then
  echo "Usage order: `basename $0` /source /destination block_size"
  exit $E_BADARGS
fi

source=$1
destination=$2
block_size=$3


progress_bar_and_copy ()
{
    src_file_size=$(stat -c %s $src) || return $?
    dest_file_size=0
    bs=$block_size
    width=${3:-25}
    mega=$(( 1024 * 1024 ))
    start=$(date +%s)
    dd if=$src 2>/dev/null | (
    while [[ dest_file_size -lt src_file_size ]]
    do
        dd bs=$bs 2>/dev/null || return $?
        (( dest_file_size += $mega ))
        [[ dest_file_size -gt src_file_size ]] && dest_file_size=$src_file_size

        # Вывод имени файлов
        name=$(basename $src | cut -b -20)
        printf "\r%-20s " $name 1>&2

        # Вывод процентов
        percent=$(( 100 * $dest_file_size / $src_file_size ))
        printf "%3d%% [" $percent 1>&2

        # Вывод progress bar`а
        progress_bar=$(( $width * $dest_file_size / $src_file_size ))
        for i in $(seq 1 $progress_bar); do printf "=" 1>&2; done
        for i in $(seq $progress_bar $(( $width-1 ))); do printf " " 1>&2; done

        # Вывод скопированного
        if [[ $dest_file_size -le 1024 ]]; then
            printf -v size "%d" $dest_file_size;
        elif [[ $dest_file_size -le $mega ]]; then
            printf -v size "%d kB" $(( $dest_file_size / 1024  ));
        else
            printf -v size "%d MB" $(( $dest_file_size / $mega ));
        fi
        printf "] %7s" "$size" 1>&2

        # Вывод примерного времени
        elapsed=$(( $(date +%s) - $start ))
        remain=$(( $src_file_size - $dest_file_size ))
        eta=$(( ($elapsed * $remain) / $dest_file_size + 1))
        if [[ $remain == 0 ]]; then eta=0; fi
        etamin=$(( $eta / 60 ))
        etasec=$(( $eta % 60 ))
        if [[ $eta > 0 ]]; then etastr="ETA"; else etastr="   "; fi
        printf "   %02d:%02d $etastr" $etamin $etasec 1>&2
    done
    echo 1>&2
    ) | dd of=$dest 2>/dev/null
}


cd $source 2>/dev/null
errorcode_src=$?
cd $destination 2>/dev/null
errorcode_dest=$?

if [[ $errorcode_src = 0 && $errorcode_dest = 0 ]] ;  then
    cd .
        find $source -follow -type f | while read line;
            do
                dest="$destination""$line"
                    src=$line
                        dir=`dirname $dest`
                            mkdir -p $dir
                                bs=$block_size
                                    progress_bar_and_copy
                                    done
        else
            if [[ $errorcode_src = 1 && $errorcode_dest = 1 ]] ;  then
                cd .
                    src=$source
                        dest=$destination
                            bs=$block_size
                                progress_bar_and_copy
                                else
                                echo error!
                                echo Check up paths!
        exit 0
    fi
fi