Возникла проблемка:
имеются два каталога /src и /destВ них содержатся поткаталоги в которых соответственно есть файлы, их очень много.
Задача значит такая скопировать рекурсивно из каталога /src в каталог /dest.
можно конечно писать файлик типа:
dd if=/src/dir1/file1.dbf of=/src/dir1/file1.dbf bs=50MНо для тысяч файлов это не практично и ошибиться можно, почему именно dd, потому что отключено кеширование на дисках.
Вопрос: куда копать и как быть? Кто может сталкивался?
>[оверквотинг удален]
>В них содержатся поткаталоги в которых соответственно есть файлы, их очень много.
>
>Задача значит такая скопировать рекурсивно из каталога /src в каталог /dest.
>можно конечно писать файлик типа:
>dd if=/src/dir1/file1.dbf of=/src/dir1/file1.dbf bs=50M
>
>Но для тысяч файлов это не практично и ошибиться можно, почему именно
>dd, потому что отключено кеширование на дисках.
>
>Вопрос: куда копать и как быть? Кто может сталкивался?pax(1)
>pax(1)Спасибо :)
Щас попробую этого зверя
>>pax(1)
>
>Спасибо :)
>
>Щас попробую этого зверяНе pax не подходит, скорость копирования сравнима с cp - нужно большую которая дает dd ^(
>Не pax не подходит, скорость копирования сравнима с cp - нужно большую
>которая дает dd ^(rsync не подойдёт?
>>Не pax не подходит, скорость копирования сравнима с cp - нужно большую
>>которая дает dd ^(
>
>rsync не подойдёт?Промышленный сервер с AIX там нет ни rsync ни gcc и ставить нельзя их, так что нужно решать вопрос стандартными средствами.
>>>pax(1)
>>
>>Спасибо :)
>>
>>Щас попробую этого зверя
>
>Не pax не подходит, скорость копирования сравнима с cp - нужно большую
>которая дает dd ^(тогда остается рекурсивно обходить каталоги и для каждого файла вызывать дд
>тогда остается рекурсивно обходить каталоги и для каждого файла вызывать дд... что в общем-то несложно, имея под рукой find, dirname, basename и т.д.
>>тогда остается рекурсивно обходить каталоги и для каждого файла вызывать дд
>
>... что в общем-то несложно, имея под рукой find, dirname, basename и
>т.д.и получим тот же ср или rsync :)
>>>тогда остается рекурсивно обходить каталоги и для каждого файла вызывать дд
>>
>>... что в общем-то несложно, имея под рукой 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
>[оверквотинг удален]
>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К сожалению проверить на данный момент негде...
Да господь с вами, что вы такое пишете!? Какой ещё цикл, какие списки (и вообще, что означает конструкция `source_dir`?)? Опция -exec у find'а - вот, что здесь нужно. И какой ещё count=10000? Что, файлы длиннее 100G недостойны быть скопированы целиком? Не нужно вообще никакой предел указывать.
>Да господь с вами, что вы такое пишете!? Какой ещё цикл, какие
>списки (и вообще, что означает конструкция `source_dir`?)? Опция -exec у
>find'а - вот, что здесь нужно. И какой ещё count=10000? Что,
>файлы длиннее 100G недостойны быть скопированы целиком? Не нужно вообще никакой
>предел указывать.count=10000 и source_dir это просто пример.
Хотел бы я посмотреть как ты вставишь find .. exec`ом параметры в dd if=?? of=?? :):)
>Хотел бы я посмотреть как ты вставишь find .. exec`ом параметры в
>dd if=?? of=?? :):)Ну так и быть, смотрите:
#!/bin/shif [ "$1" = '' -o "$2" = '' ]; then
echo "Usage: $0 src_dir dst_dir" >&2
exit 1
ficd $2
cd -
DST=$OLDPWD
cd $1find -type d -exec mkdir -p $DST/\{\} \;
find -type f -exec dd bs=10M if=\{\} of=$DST/\{\} \;
Это так, за пару минут сляпал. Дальше уж сами как-нибудь...
>[оверквотинг удален]
>
>cd $2
>cd -
>DST=$OLDPWD
>cd $1
>
>find -type d -exec mkdir -p $DST/\{\} \;
>find -type f -exec dd bs=10M if=\{\} of=$DST/\{\} \;
>
Спасибо :) Надо попробовать.
>Задача значит такая скопировать рекурсивно из каталога /src в каталог /dest.
>можно конечно писать файлик типа:
>dd if=/src/dir1/file1.dbf of=/src/dir1/file1.dbf bs=50Mfind ... | cpio -p -C 52428800 ...
>>Задача значит такая скопировать рекурсивно из каталога /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 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. Основная проблема - полёты головы между чтением и записью. Для борьбы с нею достаточно создать большой буфер на любой стороне.
А такой вариант не подойдет?tar -cvf - -C /src . | tar -xpvf - -C /dest/
Недавно копировал таким способом 25 гигов - заняло примерно 20 минут SAS HDD -> SATA HDD.
>А такой вариант не подойдет?
>
>tar -cvf - -C /src . | tar -xpvf - -C /dest/
>
>
>Недавно копировал таким способом 25 гигов - заняло примерно 20 минут SAS HDD -> SATA HDD.Нет слишком медленно, когда нужно копировать терабайты данных.
>А такой вариант не подойдет?
>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/...), архив - в конвейер, конвейер читать-писать кусками такого-то размера(=буферизовать), "на той стороне" - распаковать из архива в указанную директорию.
Хотя идея диска и без буферизации -- пуга-а-ает. %)
>
>Хотя идея диска и без буферизации -- пуга-а-ает. %)Орокля крутится там, в аиксе на тех дисках нужно отключать буферизацию в системе, а орокля свою систему использует
>Орокля
>в аиксе
>отключать буферизациюНу, я так и подумал, что задача так же крива, как и её решение. $))
>[оверквотинг удален]
>В них содержатся поткаталоги в которых соответственно есть файлы, их очень много.
>
>Задача значит такая скопировать рекурсивно из каталога /src в каталог /dest.
>можно конечно писать файлик типа:
>dd if=/src/dir1/file1.dbf of=/src/dir1/file1.dbf bs=50M
>
>Но для тысяч файлов это не практично и ошибиться можно, почему именно
>dd, потому что отключено кеширование на дисках.
>
>Вопрос: куда копать и как быть? Кто может сталкивался?Все народ решил я проблему с dd ураа, если хотите могу выложить :)
>[оверквотинг удален]
>>можно конечно писать файлик типа:
>>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;
fiecho $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
fiif [ "$create_files" = "y" -o "$create_files" = "n" ]
then
echo
else
echo "The create command files is incorrectly entered!"
sleep 3
helps
exit 0
fiif [ "$copy_dd" = 'y' -o "$copy_dd" = 'n' ]
then
echo
else
echo "The copy on dd command is incorrectly entered!"
sleep 3
helps
exit 0
fiif [ "$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
fiif [ "$rm_files_and_dir" = 'y' ]
then
echo
rm_files_dest
else
echo
fiif [ "$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
firun
Мама дорогая... Вам зарплату за строчки что-ли платят?вот это очень порадовало (:
input_source () {
find $src -follow -type f | while read string
do
echo $string
done
}
>[оверквотинг удален]
>
>вот это очень порадовало (:input_source () {
>
> find $src -follow -type f | while
>read string
>
>do
> echo $string
> done
>}Согласен код не самый оптимальный но я и не шелловский гуру
главное работает :)
Вот новый скриптец, доработанный маленький и с прогресс баром для копирования с помощью 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
fisource=$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