Linux за българи: Форуми

Linux секция за начинаещи => Настройка на програми => Темата е започната от: Ivshti в Sep 08, 2008, 18:16



Титла: Копиране на файлове, създадени скоро в...
Публикувано от: Ivshti в Sep 08, 2008, 18:16
Здрайвете, моля за помощта ви относно този въпрос:
Как мога да копирам всички файлове от дадени директории, създадени/модифицирани през последните 30 минути (find /{direktoriq, direktoriq} -mmin -30) в определена директория.
Целта ми е всичките файлове, създадени/модифицирани в последните 30 минути, които се намират в etc, lib, sbin, srv, usr, var да се копират във /tmp/root така, че примерно ако имам един файл
/etc/asd.conf
Да се копира тук: /tmp/root/etc/asd.conf

Пробвах със sed, cp и xargs така:
Примерен код
find /{etc,lib,sbin,srv,usr,var} -mmin -30 | sed -e 's~.*~& /tmp/root&~' | xargs cp -a


Нямам си понятие защо не е станало. Може би защото трябва да създам директориите в /tmp/root, но не мога да експериментирам, защото имам само един опит, работя във виртуална машина и в момента е на saved state. :)

Благодаря предварително!


Титла: Копиране на файлове, създадени скоро в...
Публикувано от: VladSun в Sep 08, 2008, 18:55
http://content.hccfl.edu/pollock/unix/findcmd.htm

Примерен код
find /{etc,lib,sbin,srv,usr,var} -mmin -30  -exec cp '{}'  /tmp/root \;






Титла: Копиране на файлове, създадени скоро в...
Публикувано от: Ivshti в Sep 08, 2008, 19:35
VladSun, да, работи, но пак получавам същия резултат: ако файла е /etc/asd.conf, то го копира в /tmp/root/, а искам да е в /tmp/root/etc





Титла: Копиране на файлове, създадени скоро в...
Публикувано от: VladSun в Sep 08, 2008, 19:42
дублиран





Титла: Копиране на файлове, създадени скоро в...
Публикувано от: VladSun в Sep 08, 2008, 19:43
пробвай с -R опцията на cp
т.е.
Примерен код
find /{etc,lib,sbin,srv,usr,var} -mmin -30  -exec cp -R '{}'  /tmp/root \;


EDIT: Макар, че като се замисля едва ли ще стане това, което искаш.





Титла: Копиране на файлове, създадени скоро в...
Публикувано от: Ivshti в Sep 08, 2008, 19:55
Сега пък работи така:
Ако има файл /etc/asd/asd.conf, то го копира в /tmp/root/asd/asd.conf :)
Това е защото find ги връща нещата по такъв коварен начин :)
Но и това върши работа, ще копирам всичко от целия руут (освен ако не запецне на нещо от /dev, там има файлове, които могат безкрай да се копират :D )
И все пак, точно преди да започна процедурата искам да попитам, може ли да се филтрират директории от файнд, така че пак да си търси из тия директории, но да връща пълен път (e.g. /usr/bin/executable), а не (./bin/executable) :)

ПП: прегледах онзи манюъл, което постна, но не намерих нещо в man страниците на find също няма такова (губя надежда за такава опция). Потърсих с man find | grep filter





Титла: Копиране на файлове, създадени скоро в...
Публикувано от: VladSun в Sep 08, 2008, 20:12
OK ...
Правиш си един файл:

/sbin/myarch
Примерен код
#!/bin/bash
dn=`dirname $1`
mkdir -p $2/$dn && cp $1 $2/$1


chmod 0700 /sbin/myarch

и след това:

Примерен код
find /{etc,lib,sbin,srv,usr,var} -type f -mmin -30  -exec myarch '{}' /temp/root \;






Титла: Копиране на файлове, създадени скоро в...
Публикувано от: Ivshti в Sep 08, 2008, 20:21
Мдааа, това проработи, много ти благодаря :)
Жив и здрав да си :D


Титла: Копиране на файлове, създадени скоро в...
Публикувано от: VladSun в Sep 08, 2008, 22:47
То всичко хубаво, ама аз лично си скъсах нервите да разбера защо:
Примерен код
find /{etc,lib,sbin,srv,usr,var} -type f -mmin -30  -exec echo `dirname '{}'` \;

изкарва само точки, а
Примерен код
find /{etc,lib,sbin,srv,usr,var} -type f -mmin -30  -exec dirname '{}' \;

си изкарва правилно имената на директориите, а
Примерен код
find /{etc,lib,sbin,srv,usr,var} -type f -mmin -30  -exec echo `basename '{}'` \;

си изкарва правилно имената на файловете.

Е ... не успях да разбера:)
някой с идеи по въпроса?





Титла: Копиране на файлове, създадени скоро в...
Публикувано от: phantomlord в Sep 09, 2008, 02:20
Аз имам друг въпрос, но донякъде е свързан с темата... Имам една директория с n под-директории... Трябва ми нещо, което да намери съвпадение на файлове по име и разширение в тях и да остави само по един от тях.


Титла: Копиране на файлове, създадени скоро в...
Публикувано от: Hapkoc в Sep 09, 2008, 09:11
VladSun, таман се сблъсках със същия проблем... :)

При find ... -exec echo `dirname {}` шела заменя нещото в обратните кавички още при изпълнението на командата, т.е. `dirname {}` стига до find-а във вид ".".


Титла: Копиране на файлове, създадени скоро в...
Публикувано от: VladSun в Sep 09, 2008, 12:45
@phantomlord

Примерен код
#!/bin/bash

find $1 -type f > /tmp/sdr.all.files.$$
find $1 -type f -exec basename '{}' > /tmp/sdr.all.basenames.$$ \;
cat /tmp/sdr.all.basenames.$$ | sort | uniq -d > /tmp/sdr.dup.basenames.$$

for filename in `cat /tmp/sdr.dup.basenames.$$`; do
    FIRST=1
    for file in `grep "$filename\$" /tmp/sdr.all.files.$$`; do
        if [ $FIRST -eq 1 ]; then
            echo "[+] Leaving $file"
        else
            echo "      [-] Deleting $file"
        fi
        FIRST=0
    done
done

rm /tmp/sdr.all.files.$$
rm /tmp/sdr.all.basenames.$$
rm /tmp/sdr.dup.basenames.$$


Може да не е най-елегантното решение, ама си работи :)





Титла: Копиране на файлове, създадени скоро в...
Публикувано от: VladSun в Sep 09, 2008, 12:46
Цитат (Hapkoc @ Сеп. 09 2008,09:11)
VladSun, таман се сблъсках със същия проблем... :)

При find ... -exec echo `dirname {}` шела заменя нещото в обратните кавички още при изпълнението на командата, т.е. `dirname {}` стига до find-а във вид ".".

Блях ...
А защо с `basename {}` няма проблеми?!?

EDIT: Няма проблеми друг път!
basename пък изкарва целия път ... все едно го няма...





Титла: Копиране на файлове, създадени скоро в...
Публикувано от: VladSun в Sep 09, 2008, 12:54
Блях ...

Примерен код
find /{etc,lib,sbin,srv,usr,var} -type f -mmin -30  -exec echo `{}` \;
-bash: {}: command not found


Примерен код
root@designer:/home/vladsun# find /{etc,lib,sbin,srv,usr,var} -type f -mmin -30  -exec `echo dirname {}` \;
/var/log
/var/log
/var/log
/var/log/exim4
root@designer:/home/vladsun# find /{etc,lib,sbin,srv,usr,var} -type f -mmin -30  -exec `echo basename {}` \;
messages
auth.log
syslog
mainlog






Титла: Копиране на файлове, създадени скоро в...
Публикувано от: rpetrov в Sep 09, 2008, 13:01
За GNU cp опцията --parents ще копира с името на директорията.

Освен това `dirname {}`, се изпълнява от командния интерпретатор, първо, още преди да се извика командата find. За да се подаде на -exec , по-скоро трябва да е ... -exec /bin/sh -c 'echo `basename {}`' ...


Титла: Копиране на файлове, създадени скоро в...
Публикувано от: Ivshti в Sep 09, 2008, 13:03
Ми даа... не може да се оправи и с $(basename '{}';) щото и там не се парсва
Примерен код
[ivo@localhost ~]$ find /{etc,lib,sbin,srv,usr,var} -type f -mmin -30  -exec echo $({}) \;
bash: {}: command not found

Това не трябва ли да се води бъг във find?
VladSun: за проблема на phantomlord, мислех някакво решение да прави масив с уникалните файлове и на всеки файл да проверява дали basename-а му съвпада с някой от уникалните файлове, ако не съвпада, файла се добавя към масива, ако съвпада, файла се изтрива.





Титла: Копиране на файлове, създадени скоро в...
Публикувано от: VladSun в Sep 09, 2008, 13:04
Мдам, усетих се :)
А пък опцията parents как съм я пропуснал - при все, че вчера прегледах man-а специално за такава опция...

Мерси :)


Титла: Копиране на файлове, създадени скоро в...
Публикувано от: Gaara в Sep 09, 2008, 13:47
Мдаааа, велика опция е parents :)
Друг вариант...
Примерен код

find /{etc,lib,sbin,srv,usr,var} -type f -mmin -30 -print0 | xargs -0 -I xxx cp -a --parents xxx /tmp/root


Титла: Копиране на файлове, създадени скоро в...
Публикувано от: phantomlord в Sep 10, 2008, 10:52
Цитат (VladSun @ Сеп. 09 2008,12:45)
@phantomlord

Примерен код
#!/bin/bash

find $1 -type f > /tmp/sdr.all.files.$$
find $1 -type f -exec basename '{}' > /tmp/sdr.all.basenames.$$ \;
cat /tmp/sdr.all.basenames.$$ | sort | uniq -d > /tmp/sdr.dup.basenames.$$

for filename in `cat /tmp/sdr.dup.basenames.$$`; do
    FIRST=1
    for file in `grep "$filename\$" /tmp/sdr.all.files.$$`; do
        if [ $FIRST -eq 1 ]; then
            echo "[+] Leaving $file"
        else
            echo "      [-] Deleting $file"
        fi
        FIRST=0
    done
done

rm /tmp/sdr.all.files.$$
rm /tmp/sdr.all.basenames.$$
rm /tmp/sdr.dup.basenames.$$


Може да не е най-елегантното решение, ама си работи :)

Дам, свърши работа :)
Много благодаря!