elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.
 
Inicio Ayuda Buscar Ingresar Registrarse
23 Febrero 2012, 02:36  

Tema destacado:


+  Foro de elhacker.net
|-+  Programación
| |-+  Scripting (Moderadores: Novlucker, Leo Gutiérrez.)
| | |-+  [Bash] Script de copia-backup archivos nuevos
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: [Bash] Script de copia-backup archivos nuevos  (Leído 1,809 veces)
sclub


Desconectado Desconectado

Mensajes: 590



Ver Perfil
[Bash] Script de copia-backup archivos nuevos
« en: 19 Diciembre 2010, 21:38 »

holaaa!!

aver, estoy intentando hacer un script que me sincronize dos unidades, una que me lllevo d'aquí p'allá, y la otra que la tengo en casa siempre.
El codigo es este:
Código
#!/bin/bash
 
copiaRecurs() {
src="$1"
dst="$2"
for file in $(ls $src)
do
if [ -d "$src/$file" ]; then
if [ ! -e "$dst/$file" ]; then
mkdir "$dst/$file"
fi
`copiaRecurs "$src/$file" "$dst/$file"`
else
if [ "$src/$file" -nt "$dst/$file" ]; then
cp "$src/$file" "$dst/$file"
fi
fi
done
}
 
pathB="/media/BOX"
pathS="/media/STORE"
 
boxSof="Softw"
strSof="Software"
boxDoc="Doc"
strDoc="Documentacio"
boxImg="Images"
strImg="Images"
 
if [ ! -d $pathB ]; then
echo "BOX isn't ready!"
exit
else
if [ ! -d $pathS ]; then
echo "STORE isn't ready!"
exit
fi
fi
 
copiaRecurs "$pathB/$boxImg" "$pathS/prova"
 
echo "Cool!!"
 

El problema que estoy teniendo es que no me copia todo... alguna carpeta me la deja vacia. Aparte mientras se esta copiando saltan algunos 'errores' como estos:
Código:
./scripts/syncro.sh: line 12: `/media/BOX/Images/Amsterdam\'08/Peke/DSC06339.JPG': No such file or directory
./scripts/syncro.sh: line 12: `/media/BOX/Images/BBQ(Sept\'09)/DSC00824.JPG': No such file or directory
./scripts/syncro.sh: line 12: `/media/BOX/Images/ClasseESI/Thumbs.db': No such file or directory
./scripts/syncro.sh: line 12: `/media/BOX/Images/Dublin\'09/Adventures/DSC02777.JPG': No such file or directory

Pero esos archivos SÍ existen, es más, me los copia al destino... nose... la cosa es que de una carpeta de 10gb de fotos, 1gb no se ha copiado... y solo tengo localizada una carpeta vacia... el resto deben ser fotos sueltas...
Alguien ve algo raro en el codigo¿??? Estoy empezando a hacerme mis scripts y me lio un poco.

Por otro lado, eso no es lo mismo que un cp -r verdad?? el cp -r sobreescribiria en cualquier caso, sea nuevo o no... correcto??

Bueno, gracias por leer!!

Saludos!

EDIT ---
Cambio el titulo porque al final no he usado recursividad. Código al final.


« Última modificación: 23 Diciembre 2010, 22:53 por sclub » En línea

... because making UNIX user friendly is easier than debugging Windows.
Leo Gutiérrez.
. . .. ... ..... ........ ............. .....................
Moderador
***
Desconectado Desconectado

Mensajes: 2.944


/^$/


Ver Perfil WWW
Re: Recursividad en bash
« Respuesta #1 en: 20 Diciembre 2010, 07:21 »

¿qué es lo que quieres hacer con ese script?

Lo digo para ver si hallamos otra alternativa.


En línea

Código
(( 1 / 0 )) &> /dev/null || {
echo -e "stderrrrrrrrrrrrrrrrrrr";
}
 

leorocko13@hotmail.com
https://github.com/leogtzr/
sclub


Desconectado Desconectado

Mensajes: 590



Ver Perfil
Re: Recursividad en bash
« Respuesta #2 en: 20 Diciembre 2010, 13:53 »

Pues lo que quiero es que yo le de al script, y me copie todos los archivos de BOX a STORE(son 2 HDD's).

Basicamente copia todo a otro HDD, pero solo si su igual en el destino no existe o es mas viejo. Porque sino seria mucho procesador gastado en vano... almomejor yo hay dias que solo he modificado 2 archivos de todo lo que quiero que se copie, pues solo se copiaran esos 2, no todo...

se te ocurre alguna manera mejor¿??? Se me ocurrio que el cp podria tener una opció que compruebe eso(-nt, -ot), pero no la encontré en el man... se me pasó o no la hay¿?

Saludos!!
En línea

... because making UNIX user friendly is easier than debugging Windows.
Leo Gutiérrez.
. . .. ... ..... ........ ............. .....................
Moderador
***
Desconectado Desconectado

Mensajes: 2.944


/^$/


Ver Perfil WWW
Re: Recursividad en bash
« Respuesta #3 en: 20 Diciembre 2010, 18:31 »

A mi se me ocurre usar find con sus test's, find trabaja de manera rápida.

Código
TESTS
      Some tests, for example -newerXY and -samefile, allow comparison between the file currently being examined and some reference file specified on  the  command  line.
      When  these  tests are used, the interpretation of the reference file is determined by the options -H, -L and -P and any previous -follow, but the reference file is
      only examined once, at the time the command line is parsed.  If the reference file cannot be examined (for example, the stat(2) system call fails for it), an  error
      message is issued, and find exits with a nonzero status.
 
      Numeric arguments can be specified as
 
      +n     for greater than n,
 
      -n     for less than n,
 
      n      for exactly n.
 
      -amin n
             File was last accessed n minutes ago.
 
      -anewer file
             File  was last accessed more recently than file was modified.  If file is a symbolic link and the -H option or the -L option is in effect, the access time of
             the file it points to is always used.
 
      -atime n
             File was last accessed n*24 hours ago.  When find figures out how many 24-hour periods ago the file was last accessed, any fractional part is ignored, so  to
             match -atime +1, a file has to have been accessed at least two days ago.
 
      -cmin n
             File's status was last changed n minutes ago.
 
      -cnewer file
             File'
s status was last changed more recently than file was modified.  If file is a symbolic link and the -H option or the -L option is in effect, the status-
             change time of the file it points to is always used.
 
      -ctime n
             File's status was last changed n*24 hours ago.  See the comments for -atime to understand how rounding affects  the  interpretation  of  file  status  change
             times.
 
      -empty File is empty and is either a regular file or a directory.

find combinado con -exec, investigalo bien, seguro que te ayuda.
Código:
http://content.hccfl.edu/pollock/unix/findcmd.htm
En línea

Código
(( 1 / 0 )) &> /dev/null || {
echo -e "stderrrrrrrrrrrrrrrrrrr";
}
 

leorocko13@hotmail.com
https://github.com/leogtzr/
sclub


Desconectado Desconectado

Mensajes: 590



Ver Perfil
Re: Recursividad en bash
« Respuesta #4 en: 21 Diciembre 2010, 00:10 »

Código
#!/bin/bash
 
IFS=$'\x0A'$'\x0D'
 
copiaRecurs() {
srcFolder="$1"
dstFolder="$2"
 
cd $srcFolder
 
for srcFile in $(find .)
do
 
dstFile="$dstFolder/$srcFile"
if [ -d "$srcFile" ]; then
if [ ! -e "$dstFile" ]; then
mkdir "$dstFile"
fi
else
if [ ! -e "$dstFile" ]; then
cp "$srcFile" "$dstFile"
else
#find "$srcFile" -cnewer "$dstFile" -exec sh -c 'exec cp -f "$@" $dstFile' find-copy {} +
if [ "$srcFile" -nt "$dstFile" ]; then
cp -f "$srcFile" "$dstFile"
fi
fi
fi
done
}
 
pathB="/media/BOX"
pathS="/media/STORE"
 
copiaRecurs "$pathB/prova" "$pathS/prova"

Me ha venido bien el find! ;) el problema fue que los espacios me los detectaba como un salto de linea y me daba error... al final encontre que si canviaba los caracteres que se imprimian con el espacio(IFS) podia poner unos que son tratados correctamente. :)

Pero segui teniendo un problema... no me actualizaba los archivos. Copiaba lo que no existia, pero si ya existia otro paquete más viejo... me daba error.
Citar
# ./syncro.sh
cp: missing destination file operand after `./jkuadgs'
Try `cp --help' for more information.
Eso con el find... supongo que porque no lo se usar correctamente.

Entonces simplemente decicdi comprobarlo con un if y copiar manualmente. Y ya parece que va bien!

Le ves algún inconveniente a este metodo?? o ves algún fallo con la linea del find??

Saludos y gracias!!
En línea

... because making UNIX user friendly is easier than debugging Windows.
Leo Gutiérrez.
. . .. ... ..... ........ ............. .....................
Moderador
***
Desconectado Desconectado

Mensajes: 2.944


/^$/


Ver Perfil WWW
Re: Recursividad en bash
« Respuesta #5 en: 21 Diciembre 2010, 07:37 »

La sintaxis sería:

find OPCIONES -exec cp -f {} DESTINO \;

Te dejo un ejemplo:


Código
leo@leo-desktop:~/Escritorio$ find . -type f -iname "vocabulario.txt" -exec cp -vf {} /home/leo/ \;
«./vocabulario.txt» -> «/home/leo/vocabulario.txt»
leo@leo-desktop:~/Escritorio$
 

{} Hace referencia al archivo en cuestión.
/home/leo/ sería el destino.

\; Necesario para terminar el find.
En línea

Código
(( 1 / 0 )) &> /dev/null || {
echo -e "stderrrrrrrrrrrrrrrrrrr";
}
 

leorocko13@hotmail.com
https://github.com/leogtzr/
sclub


Desconectado Desconectado

Mensajes: 590



Ver Perfil
Re: Recursividad en bash
« Respuesta #6 en: 21 Diciembre 2010, 19:50 »

Perfecto!!! ;-) Ya funciona!

El problema es que no sabia como se usaba el -exec y no encontre una explicación clara con buenos ejemplos que reflejaran mi caso. Pero ahora ya está!! Muchas gracias!!! ;)

Aunque sigo teniendo una duda, las rutas con las que trabajo son así:
Citar
/media/BOX/./Images/
y queria sustituirlo por:
Citar
/media/BOX/Images/

así que probe con esto:
Código
dstFile=$(sed 's/"./"/"$dstFolder"/' "$srcFile")
y con esto:
Código
dstFile=$(echo "$srcFile" | sed -e 's/"./"/"$dstFolder"/')
con este error:
Citar
sed: -e expression #1, char 8: unknown option to `s'

o así:
Código
dstFile=$(echo "$srcFile" | sed -e 's/".\/"/"$dstFolder"/')
sin ningún error, pero sin resultado.

Imagino como no, que el problema será la sintaxis... aver si lo arreglo.
De todas formas, muchas gracias por la ayuda!! Qué de mi sin tí.... xDD

Saludos!!
« Última modificación: 21 Diciembre 2010, 19:55 por sclub » En línea

... because making UNIX user friendly is easier than debugging Windows.
Leo Gutiérrez.
. . .. ... ..... ........ ............. .....................
Moderador
***
Desconectado Desconectado

Mensajes: 2.944


/^$/


Ver Perfil WWW
Re: Recursividad en bash
« Respuesta #7 en: 21 Diciembre 2010, 22:10 »

Pon el código completo, por favor, para que otros vean cómo quedó.

Respecto a sed.

Código
echo -e "$string" | sed "s/\.\///g"
En línea

Código
(( 1 / 0 )) &> /dev/null || {
echo -e "stderrrrrrrrrrrrrrrrrrr";
}
 

leorocko13@hotmail.com
https://github.com/leogtzr/
sclub


Desconectado Desconectado

Mensajes: 590



Ver Perfil
Re: Recursividad en bash
« Respuesta #8 en: 23 Diciembre 2010, 22:52 »

Claro!! El retraso fue que me quedé sin cargador del portatil...  :¬¬

Código completo:
Código
#!/bin/bash
 
IFS=$'\x0A'$'\x0D'
 
copiaRecurs() {
srcFolder="$1"
dstFolder="$2"
 
cd $srcFolder
 
for srcFile in $(find .)
do
srcFile=$(echo -e "$srcFile" | sed "s/\.\///g")
dstFile="$dstFolder/$srcFile"
 
if [ -d "$srcFile" ]; then
if [ ! -e "$dstFile" ]; then
mkdir -v "$dstFile"
fi
else
if [ ! -e "$dstFile" ]; then
cp -v "$srcFile" "$dstFile"
else
find "$srcFile" -cnewer "$dstFile" -exec cp -fv {} "$dstFile" \;
fi
fi
done
}
 
pathB="/media/BOX"
pathS="/media/STORE"
 
fldDAISrc="CFGS DAI2"
fldDAIDst="Workstore/CFGS DAI2"
fldSof="Softw"
fldDoc="Doc"
fldImg="Images"
 
if [ ! -d $pathB ]; then
echo -e "BOX isn't ready!"
exit
else
if [ ! -d $pathS ]; then
echo -e "STORE isn't ready!"
exit
fi
fi
 
echo -e "-----------------------"
echo -e " 1.- Update Software"
echo -e " 2.- Update Homework"
echo -e " 3.- Update Doc"
echo -e " 4.- Update Pictures"
echo -e " 5.- Update Everything"
echo -e "-----------------------"
echo -e " 6.- Custom Update"
echo -e "-----------------------"
read -p "  Option: " opc
 
case $opc in
1)
copiaRecurs "$pathB/$fldSof" "$pathS/$fldSof";;
2)
copiaRecurs "$pathB/$fldDAISrc" "$pathS/$fldDAIDst";;
3)
copiaRecurs "$pathB/$fldDoc" "$pathS/$fldDoc";;
4)
copiaRecurs "$pathB/$fldImg" "$pathS/$fldImg";;
5)
copiaRecurs "$pathB/$fldSoft" "$pathS/$fldSoft"
copiaRecurs "$pathB/$fldDAISrc" "$pathS/$fldDAIDst"
copiaRecurs "$pathB/$fldDoc" "$pathS/$fldDoc"
copiaRecurs "$pathB/$fldImg" "$pathS/$fldImg"
;;
6)
echo -e "----------------------------------------------"
echo -e " Both paths must exist before start copying!!"
echo -e "----------------------------------------------"
read -p "Enter the full source path: " srcCustom
if [ ! -d $srcCustom ]; then
echo -e "The path you provided do not exist!"
else
read -p "Enter the full destination path: " dstCustom
if [ ! -d $dstCustom ]; then
echo -e "The path you provided do not exist!"
else
copiaRecurs $srcCustom $dstCustom
fi
fi
;;
esac
 
echo "Cool!!"
 

Se me ha ocurrido ponerle una barra de progreso y alguna tonteria más, por trastear un poco más con bash, pero de momento ya cumple su función. :D

Gracias por la ayuda!
« Última modificación: 23 Diciembre 2010, 22:54 por sclub » En línea

... because making UNIX user friendly is easier than debugging Windows.
Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Recursividad
Programación C/C++
exec.- 10 1,075 Último mensaje 14 Abril 2009, 19:55
por Eternal Idol
recursividad
Ejercicios
Choclito 0 1,339 Último mensaje 12 Mayo 2009, 04:47
por Choclito
recursividad « 1 2 »
Programación C/C++
andaluz 15 2,041 Último mensaje 17 Marzo 2010, 23:54
por Didacso
Recursividad
Programación C/C++
Abanda_9 4 1,452 Último mensaje 29 Mayo 2010, 04:09
por Abanda_9
[Bash script] equivalente de goto en batch para bash (SOLUCIONADO)
Scripting
moikano→@ 4 2,197 Último mensaje 4 Noviembre 2010, 15:58
por moikano→@
Powered by SMF 1.1.16 | SMF © 2006-2008, Simple Machines