bash: /usr/bin/find: Argument list too long

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Boudewijn
  • Registratie: Februari 2004
  • Niet online

Boudewijn

omdat het kan

Topicstarter
Hoi,


Ik heb een red hat doos bij een klant van een klant staan waar een directory op leeg gemieterd moet worden waar 370k files in staan (niet mijn idee).

De files in die directory ouder dan 1 jaar moeten weg-gepleurd worden, maar zelfs find gaat hiervan ovre de zeik qua argument list:
code:
1
2
[root@foo~]# find /bar/* -mtime +365
bash: /usr/bin/find: Argument list too long


Dus als je dit naar xargs gaat voeren word je alsnog niet blij. Idem voor find -exec.


Hier lees ik wat suggesties:

http://www.linuxjournal.com/article/6060

Een kernel recompilen is geen mogelijkheid.


Mijn plan is nu dit (leve creatief copy-pasten), en het is beetje bij beetje aangepast dus lees aub even de hele post voor je commentaar geeft. Mijn denkproces zit er ook in verwerkt.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# Author: foo@bar.
# Purpose : remove all files older than $AGE  from directory in the commandline argument
# Arguments: The directory to be purged
# Return value: None

# enter the maximum age of the file to remain preserved in seconds.
# i.e. [365*24*60*60] makes sure *only* files older than a year get removed!

AGE=$[365*24*60*60]


function larger_rm ()
{       while read filename; do
           echo $filename
           NOW=`date +%s`
           echo $NOW
           OLD=`stat -c %Z $filename`
           echo $OLD
           FILE_AGE= $[$NOW-$OLD]

           if [ $FILE_AGE -gt $AGE ]; then
               rm -rf $filename
               ls -al $filename
           fi
        done
}



ls -1 -R $1 | larger_rm

Maar ook dit werkt dus niet omdat ik een listing krijg in de vorm van:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
./testdata:
1m-old
1y-old
2m-old
2y-old
3m-old
3y-old
4m-old
testdata

./testdata/testdata:
1m-old
1y-old
2m-old
2y-old
3m-old
3y-old
4m-old


Goed, we zie hier dus 2 cases:

1: File
2: ${directory}:

Wat ik natuurlijk kan doen is:
Van filenames de : afhalen met cut en dan met bash gaan testen of het een directory is. Nadeel is wel dat dit 400k keer gebeurt (okay de initiele string comparison), en dus best wat performance kost. Als het inderdaad een directory is ignoren we die handel: hij wordt toch recursief gelist. Enige nadeel wat je kunt hebben is dat de directory structuur niet wordt verwijderd. Nou ja dat accepteer ik dan nu (!) maar even.

Kan dat niet handiger?


Hmm nu ik erover nadenk: als ik een gewone rm doe gooi ik die dirs toch al niet weg, dus waarom erop checken. Ergo, hatseflats:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# Author: Boudewijn for foobar BV.
# Purpose : remove all files older than $AGE  from directory in the commandline argument
# Arguments: The directory to be purged
# Return value: None

# enter the maximum age of the file to remain preserved in seconds.
# i.e. [365*24*60*60] makes sure *only* files older than a year get removed!

AGE=$[365*24*60*60]


function larger_rm ()
{       while read filename; do
           echo $filename

           #warning, it won't work in case of files called foo:bar
            if [[ $filename == *:* ]] ; then
             #if [[ -d 'cut -d ':' -f1' ]]  ; then
                filename=`echo $filename | cut -f1 -d':' `
             #fi
            fi
           echo $filename

           NOW=`date +%s`
           echo $NOW
           OLD=`stat -c %Z $filename`
           echo $OLD
           FILE_AGE= $[$NOW-$OLD]

           if [ $FILE_AGE -gt $AGE ]; then
               rm $filename
               ls -al $filename
           fi
        done
}



ls -1 -R $1 | larger_rm



Het probleem hierbij is dat ik nu relatieve paden ipv absolute paden uit ls krijg. Hoe doe ik dit chique? :)

i3 + moederbord + geheugen kopen?


Acties:
  • 0 Henk 'm!

  • CyBeR
  • Registratie: September 2001
  • Niet online

CyBeR

💩

Euh, wat dacht je van

code:
1
find /bar/ -mtime +365

All my posts are provided as-is. They come with NO WARRANTY at all.


Acties:
  • 0 Henk 'm!

  • _JGC_
  • Registratie: Juli 2000
  • Laatst online: 00:46
precies, of anders even dubbele quotes on je * heen doen zodat bash dat ding niet gaat expanden.

Acties:
  • 0 Henk 'm!

  • Boudewijn
  • Registratie: Februari 2004
  • Niet online

Boudewijn

omdat het kan

Topicstarter
CyBeR schreef op maandag 29 november 2010 @ 14:48:
Euh, wat dacht je van

code:
1
find /bar/ -mtime +365
Die gaat dus ook over de zeik ;)

die find met xargs of -exec werkt dus NIET. Zie ook de topictitle ;). En het staat ook letterlijk in de startpost ;). Of bedoelen jullie wat anders?

i3 + moederbord + geheugen kopen?


Acties:
  • 0 Henk 'm!

  • CyBeR
  • Registratie: September 2001
  • Niet online

CyBeR

💩

Boudewijn schreef op maandag 29 november 2010 @ 15:09:
[...]

Die gaat dus ook over de zeik ;)

die find met xargs of -exec werkt dus NIET. Zie ook de topictitle ;). En het staat ook letterlijk in de startpost ;). Of bedoelen jullie wat anders?
Die hoort niet over de zeik te gaan. Wat over de zeik gaat is namelijk niet find, maar je shell. De argument list is te lang voor je shell als je * doet in een grote directory. Maar de argument list als je '/bar' zegt is precies dat: '/bar'. Dus als dat ook over de zeik gaat op dezelfde manier doe je iets fout.

All my posts are provided as-is. They come with NO WARRANTY at all.


Acties:
  • 0 Henk 'm!

  • _JGC_
  • Registratie: Juli 2000
  • Laatst online: 00:46
Overigens heeft GNU find ook gewoon een -delete optie die je hiervoor kunt gebruiken, niks gedoe met xargs of -exec.

Acties:
  • 0 Henk 'm!

  • Boudewijn
  • Registratie: Februari 2004
  • Niet online

Boudewijn

omdat het kan

Topicstarter
Hmm inderdaad dat werkt. Lekker soepeltjes Boudewijn :/.
Inderdaad die asterisk was niet zo handig,grmbl. Maandagochtend :/.

Thanks heren.

i3 + moederbord + geheugen kopen?

Pagina: 1