Sziasztok!
Rekurzívan szeretnék egy adott mappában lévő fájlokról bizonyos információkat kinyerni, a stat programra gondoltam:
find . -exec stat --printf '%A\t%a\t%s\t%f\t%F\t%h\t%i\t%u\t%g\t%U\t%G\t%W\t%Y\t%Z\t%X\t%w\t%y\t%z\t%x\t%N\n' {} \; > test.csv
A dolog "majdnem jó" :) a "gond" hogy vannak ACL jogokkal rendelkező fájlok amiknél lehagyja a jogosultságok végén a "+" jelet.
Ha az alábbi parancsot használom:
find . -exec ls -l -d {} \; > test.txt
Akkor az egyik ACL-el rendelkező fájlhoz tartozó sor:
-rw-rw-r--+ 1 www-data www-data 8 jún 16 12:07 ./back1/file3.txt
Ugyanez a stat használatával:
-rw-rw-r-- 664 8 81b4 szabályos fájl 1 786444 33 33 www-data www-data 0 1592302074 1592306178 1592302568 - 2020-06-16 12:07:54.936730699 +0200 2020-06-16 13:16:18.413802694 +0200 2020-06-16 12:16:08.887845035 +0200 './back1/file3.txt'
Mint látható a "-rw-rw-r--" oszlop végéről hiányzik a "+" jel. (A további feldolgozás miatt szükségem van rá, mert nélküle nem kérdezi le az ACL jogokat egy másik script amit nem szeretnék módosítani..)
A probléma megoldására az alábbi Perl script-et írtam mely működik is csupán nagyon "lassú":
#!/usr/bin/perl
#karakterkészlet beállítása
#use Encode;
#use utf8;
#use open ':std', ':encoding(UTF-8)';
$_=`date`;
chomp($_);
print STDERR "\nStarted!\t( $_ )\n\nGet file list, please wait few minute...\n\n";
@filelist=`find .`;
$filelistCount=@filelist;
$i=0;
print STDERR "File list get commplette!\t( files num: $filelistCount )\n\n";
$_=`date`;
chomp($_);
print STDERR "Start processing, please wait...\t( $_ )\n\n";
print "Premissions BITS\tPremissions OCT\tSize of BYTE\tFiletype RAW\tFiletype STRING\tHard link num\tInode ID\t";
print "Owner user ID\tOwner grup ID\tOwner user\tOwner grup\t";
print "Create time UNIX\tModify time UNIX\tChanged time UNIX\tAccess time UNIX\tCreate time\tModify time\tChanged time\tAccess time\t";
print "Filename";
foreach $_ (@filelist)
{
#
chomp($_);
#print "$file\t";
$file=quotemeta($_);
$fileStat=`ls -l -d $file | awk '{ printf \$1 }'`;
print "\n$fileStat";
$fileStat=`stat --printf \'\\t\%a\\t\%s\\t\%f\\t\%F\\t\%h\\t\%i\\t\%u\\t\%g\\t\%U\\t\%G\\t\%W\\t\%Y\\t\%Z\\t\%X\\t\%w\\t\%y\\t\%z\\t\%x\\t\%N\' $file`;
print $fileStat;
$i++;
$_=`date`;
chomp($_);
print STDERR "\rProcessing... ( $filelistCount / $i )\t( $_ )";
}
$_=`date`;
chomp($_);
print STDERR "\n\nCommplette processing\t( $_ )\n\n";
print STDERR "Finish!\n\n";
Jelenleg 917873 fájlon dolgozom, maga a find parancs kb 30 másodperc alatt végez, de a script kb 9 óra alatt futott le.
Amennyiben az "egysoros find -exec stat..." megoldást használom a lefutási idő 40-60 perc ami még éppen elfogadható...
Ha külön külön futtatom le az ls-t és a stat-ot egymás után és utána "fűzöm össze" akkor a nagy idő különbség miatt valós kockázata lesz hogy nem fognak egyezni a stat és az ls által kiírt adatok...
Van megoldás rá hogy a stat is odategye azt a "+", esetleg hogy 10-20 szorosára gyorsuljon a feldolgozás?
(A date rendszerhívások, különösen a ciklusban kb 25% lassítanak, csak a "tesztelés" véget tettem bele, sajnos a kihagyásuk sem oldja meg a sebességbeli problémát.)
Bármilyen építő jellegű ötletet szívesen fogadok.
Köszönettel: Novarobot.