Re: find question

2024-01-13 Thread Greg Wooledge
On Sun, Jan 14, 2024 at 12:25:03AM +1300, Richard Hector wrote:
> Except that from the man page, -delete implies -depth. Maybe that's a
> GNUism; I don't know.

Oh, maybe that's new?  I'm not sure.  Anyway, yeah, -delete is a GNUism.
POSIX find doesn't have it at all.

> That leaves the question: When using -delete (and -depth), does the deletion
> of files within a directory update the mtime of that directory, thereby
> rendering the directory inelegible for deletion when it would have been
> before? Or is the mtime of that directory recorded before the contents are
> processed?
> 
> I just did a quick test (using -mmin -1 instead), and it did delete the
> whole lot.

I don't know the answer to that.  Even in the worst case, though, you'd
just have an empty directory sitting around until some future run of
the cleanup script.  It would eventually be removed.

On the other hand, it might Just Work as you desire.

> So I'm still unclear why sometimes the top-level directory (or a directory
> within it) gets left behind. I've just noticed that one of the directories
> (not the one in $dir) contains a '@' symbol; I don't know if that affects
> it?

find should not care about the characters in the directory name.

> I'm tempted to avoid the problem by only using find for the top-level
> directory, and exec'ing "rm -r(f)" on it. I'm sure you'll tell me there are
> problems with that, too :-)

You never said that was an allowed solution. ;-)  The only drawback
to that solution would be if you didn't *want* to remove the entire
directory recursively.  If a directory has a timestamp that makes it
eligible for cleanup, but some file down inside it does not, do you
want to remove that file anyway?  If so, then sure, -exec rm -rf {} +
will get it done.



Re: find question

2024-01-13 Thread Richard Hector

On 30/12/23 01:27, Greg Wooledge wrote:

On Fri, Dec 29, 2023 at 10:56:52PM +1300, Richard Hector wrote:

find $dir -mtime +7 -delete


"$dir" should be quoted.


Got it, thanks.


Will that fail to delete higher directories, because the deletion of files
updated the mtime?

Or does it get all the mtimes first, and use those?


It doesn't delete directories recursively.

unicorn:~$ mkdir -p /tmp/foo/bar
unicorn:~$ touch /tmp/foo/bar/file
unicorn:~$ find /tmp/foo -name bar -delete
find: cannot delete ‘/tmp/foo/bar’: Directory not empty


Understood.


But I suppose you're asking "What if it deletes both the file and the
directory, because they both qualify?"

In that case, you should use the -depth option, so that it deletes
the deepest items first.

unicorn:~$ find /tmp/foo -depth -delete
unicorn:~$ ls /tmp/foo
ls: cannot access '/tmp/foo': No such file or directory

Without -depth, it would try to delete the directory first, and that
would fail because the directory's not empty.

-depth must appear AFTER the pathnames, but BEFORE any other arguments
such as -mtime or -name.


Except that from the man page, -delete implies -depth. Maybe that's a 
GNUism; I don't know.



And how precise are those times? If I'm running a cron job that deletes
7-day-old directories then creates a new one less than a second later, will
that reliably get the stuff that's just turned 7 days old?


The POSIX documentation describes it pretty well:

-mtime n  The primary shall evaluate as true if the  file  modification
  time  subtracted  from  the  initialization  time, divided by
  86400 (with any remainder discarded), is n.

To qualify for -mtime +7, a file's age as calculated above must be at
least 8 days.  (+7 means more than 7.  It does not mean 7 or more.)


So 7 days and one second doesn't count as "more than 7 days"? It 
truncates the value to integer days before comparing?


Ah, yes, I see that now under -atime. Confusing. Thanks for pushing me 
to investigate :-)



It's not uncommon for the POSIX documentation of a command to be superior
to the GNU documentation of that same command, especially a GNU man page.
GNU info pages are often better, but GNU man pages tend to be lacking.


Understood, thanks. Though it might be less correct where GNUisms exist.

That leaves the question: When using -delete (and -depth), does the 
deletion of files within a directory update the mtime of that directory, 
thereby rendering the directory inelegible for deletion when it would 
have been before? Or is the mtime of that directory recorded before the 
contents are processed?


I just did a quick test (using -mmin -1 instead), and it did delete the 
whole lot.


So I'm still unclear why sometimes the top-level directory (or a 
directory within it) gets left behind. I've just noticed that one of the 
directories (not the one in $dir) contains a '@' symbol; I don't know if 
that affects it?


I'm tempted to avoid the problem by only using find for the top-level 
directory, and exec'ing "rm -r(f)" on it. I'm sure you'll tell me there 
are problems with that, too :-)


Apologies for the slow response - sometimes the depression kicks in and 
I don't get back to a problem for a while :-(


Cheers,
Richard



Re: find question

2023-12-29 Thread Greg Wooledge
On Fri, Dec 29, 2023 at 10:56:52PM +1300, Richard Hector wrote:
> find $dir -mtime +7 -delete

"$dir" should be quoted.

> Will that fail to delete higher directories, because the deletion of files
> updated the mtime?
> 
> Or does it get all the mtimes first, and use those?

It doesn't delete directories recursively.

unicorn:~$ mkdir -p /tmp/foo/bar
unicorn:~$ touch /tmp/foo/bar/file
unicorn:~$ find /tmp/foo -name bar -delete
find: cannot delete ‘/tmp/foo/bar’: Directory not empty

But I suppose you're asking "What if it deletes both the file and the
directory, because they both qualify?"

In that case, you should use the -depth option, so that it deletes
the deepest items first.

unicorn:~$ find /tmp/foo -depth -delete
unicorn:~$ ls /tmp/foo
ls: cannot access '/tmp/foo': No such file or directory

Without -depth, it would try to delete the directory first, and that
would fail because the directory's not empty.

-depth must appear AFTER the pathnames, but BEFORE any other arguments
such as -mtime or -name.

> And how precise are those times? If I'm running a cron job that deletes
> 7-day-old directories then creates a new one less than a second later, will
> that reliably get the stuff that's just turned 7 days old?

The POSIX documentation describes it pretty well:

   -mtime n  The primary shall evaluate as true if the  file  modification
 time  subtracted  from  the  initialization  time, divided by
 86400 (with any remainder discarded), is n.

To qualify for -mtime +7, a file's age as calculated above must be at
least 8 days.  (+7 means more than 7.  It does not mean 7 or more.)

It's not uncommon for the POSIX documentation of a command to be superior
to the GNU documentation of that same command, especially a GNU man page.
GNU info pages are often better, but GNU man pages tend to be lacking.



Re: find question

2000-08-03 Thread Alexey Vyskubov
 % find `pwd` \( -name *.log -o -name *.aux \) -exec 'rm {}' ';'
 find: rm /home/shao/report/main.log: No such file or directory

It tries to execute command rm[space]/home/shao/report/main.log. Of course
there is no such command. You should execute 'rm' with filename as a parameter;
so write

rm '{}' ';'

instead of

'rm {}' ';'


-- 
Alexey Vyskubov
(at home)
Hi! I'm a .signature virus! Copy me into your ~/.signature to help me spread!


pgpIvqpFsCyDX.pgp
Description: PGP signature


Re: find question

2000-08-03 Thread Sven Burgener
On Thu, Aug 03, 2000 at 10:11:38PM +0400, Alexey Vyskubov wrote:
  % find `pwd` \( -name *.log -o -name *.aux \) -exec 'rm {}' ';'
  find: rm /home/shao/report/main.log: No such file or directory

[snipped Alexey's solution]

It's nice to use xargs together with find. (You probably know this, but
others may not have heard of it yet)

With xargs you can write fairly readable statements as - using the
command line above as example -:

# find $(pwd) -name '*.log' -o name '*.aux' | xargs rm

Using find's -print0 option together with xargs' -0 is nice to deal with 
spaces in file names. (Samba shares come to mind :)

Might help someone...

Sven
-- 
   I am the ILOVEGNU signature virus. Just copy me to your signature.
This email was infected under the terms of the GNU General Public License.



Re: find question

2000-07-05 Thread Andrew Kae

Hello everyone,

Thank you for your support.  I have a few more questions =)

For reference, I am running Unix Sys V 4.0.



   TESTS
   Numeric arguments can be specified as

   +n for greater than n,

   -n for less than n,

   n  for exactly n.



I find this to be a bit vague.
I want to check if a directory has been accessed withing 60 days.
So I do:
$ find dir -atime -60 -print
dir
some_file

I see that dir is always printed.  Does this mean the directory has been 
accessed but its files have not?  Or does find print the directory all the 
time?


Second, a question concerning the + option for find.
If I do something like
$ find dir -atime +60 -print

Is there a ceiling as to how long it checks after 60 days?  Is it until file 
creation?


If I access a file today,
$ find dir -atime +60 -print
should not print out that file because it hasn't been accessed in more than 
60 days, right?


Finally, say file_a is in dir
$ find dir -atime +10 -print
dir
$ find dir -atime +5 -print
dir
$ find dir -atime +1 -print
dir
file_a

Then this means it's been accessed in the last 4 days, right?

One last thing, does anyone know of a command to tell me last access date of 
a file?


Thank you for bearing with me on this

Drew

Get Your Private, Free E-mail from MSN Hotmail at http://www.hotmail.com



Re: find question

2000-07-05 Thread Michalowski Thierry
Andrew Kae wrote:

 One last thing, does anyone know of a command to tell me last access date of
 a file?



Just try ls -ul
(man ls will provide you much more options)

HTH ( .02 euro)


--
Thierry Michalowski /
Edipresse Publications S.A \\\' ,  / //
Informatique de Production  \\\//_/ //'
33,av. de la gare\_-//' /  //'
1001 LAUSANNE SUISSE   \ ///  //'
phone: +41 21 349 46 26/ \\\`
mailto:[EMAIL PROTECTED]   /,)-^  _\`
  (/   \\ / \\\
Unix is user-friendly...   //  //\\\
It is just selective about who its friends are((`

This message has been checked with GRIMEsweeper which has detected a virus
embedded in this plain text message. You should now delete your entire hard
drive and rinse your eyes with soapy water to ensure it doesn't spread.




RE: find question

2000-07-03 Thread Andrew Kae

Hello,

The find's atime option seems a bit sketchy.
I've tried find dir -atime 3 -print and nothing prints out.
but when i do :
find dir -atime 2 -print
it prints stuff out.

If it's been accessed in 2 days, it's been accessed in 3 days right?

Unless it means _exactly_ 2 or 3 days, in which case, it's not a great 
feature since i have to check if directories have been accessed in 60 days!


Any suggestions or comments?

TIA


From: Sean 'Shaleh' Perry [EMAIL PROTECTED]
To: Andrew Kae [EMAIL PROTECTED]
CC: debian-user@lists.debian.org
Subject: RE: find question
Date: Fri, 30 Jun 2000 13:47:27 -0700 (PDT)


 dir1 and dir2 are web sites themselves.

 I want to know if anyone has accessed dir1 within the last 60 days.  
I've

 been using find like this:
 $ find dir1 -atime 60 -print

 Is this the correct command?

looks sane, although I think atime is only set on files.  Also, some people
turn off atime writing for a speed gain.

 Is there an easier or alternative way to find this out without looking 
at

 the logs?

there are log analyzers out there.  They give all kinds of great stats.  
look

on freshmeat.net

 How does find check on this anyway?


each file on the hard drive has data stored with it about its size, 
permisions,

time created, etc.  This is the same data ls prints.  To see what find is
doing, read the man page for stat.



Get Your Private, Free E-mail from MSN Hotmail at http://www.hotmail.com



Re: find question

2000-07-03 Thread David Wright
Quoting Andrew Kae ([EMAIL PROTECTED]):
 
 The find's atime option seems a bit sketchy.
 I've tried find dir -atime 3 -print and nothing prints out.
 but when i do :
 find dir -atime 2 -print
 it prints stuff out.
 
 If it's been accessed in 2 days, it's been accessed in 3 days right?
 
 Unless it means _exactly_ 2 or 3 days, in which case, it's not a great 
 feature since i have to check if directories have been accessed in 60 days!
 
 Any suggestions or comments?

I think you need

find spectacles

man find

Specifically:

   TESTS
   Numeric arguments can be specified as

   +n for greater than n,

   -n for less than n,

   n  for exactly n.

Cheers,

-- 
Email:  [EMAIL PROTECTED]   Tel: +44 1908 653 739  Fax: +44 1908 655 151
Snail:  David Wright, Earth Science Dept., Milton Keynes, England, MK7 6AA
Disclaimer:   These addresses are only for reaching me, and do not signify
official stationery. Views expressed here are either my own or plagiarised.



RE: find question

2000-06-30 Thread Sean 'Shaleh' Perry
 
 dir1 and dir2 are web sites themselves.
 
 I want to know if anyone has accessed dir1 within the last 60 days.  I've 
 been using find like this:
 $ find dir1 -atime 60 -print
 
 Is this the correct command?

looks sane, although I think atime is only set on files.  Also, some people
turn off atime writing for a speed gain.

 Is there an easier or alternative way to find this out without looking at 
 the logs?

there are log analyzers out there.  They give all kinds of great stats.  look
on freshmeat.net

 How does find check on this anyway?
 

each file on the hard drive has data stored with it about its size, permisions,
time created, etc.  This is the same data ls prints.  To see what find is
doing, read the man page for stat.



Re: find question (and xargs)

1996-05-19 Thread Joseph Skinner


On Wed, 15 May 1996, Craig Sanders wrote:

 
 On 14 May 1996, Kai Henningsen wrote:
 
  It's find that does the replacing. None of the {}s are in the find
  arguments, however. (And rm is not even in the xargs arguments!)
 
  Personally, I'd probably make a script for the split-and-remove, but
  it should also work with a shell function.
 
 A function probably wont work - without some overly complicated tricks,
 a shell function is only available within the context/scope of the shell
 or shell script which defines it.  Programs forked by that shell or
 shell script can't exec it because it's not a program as far as they're
 concerned.
 
 This seems weird and possibly counter-intuitive, but it does make sense.
 
 It can produce some very unexpected behaviour if you're not used to
 it. 
 
 My rule of thumb is to only use functions within the context of a
 specific shell script, and not to expect them to be available in
 sub-shells or shell scripts where they haven't been explicitly defined.
 Of course, i could start all shell scripts with something like source
 ~/myfuncs.sh but that would be overkill (and ugly!).
 
 
  Anyway, I'd probably try something like this:
  
  find / -size +459976c -noleaf -type f -name '*.deb' -exec split.sh {} \;
  
  #! /bin/sh
  dpkg-split -s $1  rm $1
 
 if you're going to write a script, it's faster to use xargs, that way
 the script only needs to be forked once.
 
 
 find / -size +459976c -noleaf -type f -name '*.deb' | xargs split.sh 
 
 #! /bin/bash
 for pkg in $@ ; do 
   dpkg-split -s $pkg  rm $pkg
 done
 
 
 split.sh could even be written to take a list of files on stdin and process
 them accordingly.  more effort than what it's worth IMO, let xargs do the
 job :-)


Why not just use

for i in `find / -size +457776c -type f -name '*.deb'` ; do
   dpkg-split -s $i  rm $i
done

this gets rid of xargs altogether and seems easier to type as well [as 
long as you get all the quotes and backquotes right.

Joe.

ps. I don't use bash that much so I hope that this is right, the same 
sort of thing works in rc and I use it frequently.


Re: find question (and xargs)

1996-05-17 Thread Ian Jackson
Erick Branderhorst writes (find question (and xargs)):
 this might be a more unix oriented question but I'll ask it anyway 
 because it is very debian related too:
 
 I would like to find packages bigger than 459976 bytes and split them
 with dpkg-split, if splitting is succesfull I'll remove the package.
 I have come at the following but it doesn't work (and can't figger 
 out why not from the manpages).
 
 find / -size +459976c -noleaf -type f -name '*.deb'|\
 xargs -n 1 dpkg-split -s {}  rm {}
 
 I was thinking that {} would be replaced by the filename but that's
 not the case. Anyone know how to solve this?

Your problem is that your command
 find / -size +459976c -noleaf -type f -name '*.deb'| xargs -n 1 dpkg-split -s 
{}  rm {}
is being broken up by the shell into
 find / -size +459976c -noleaf -type f -name '*.deb'| xargs -n 1 dpkg-split -s 
{} \
  \
 rm {} \
so that the it runs dpkg-split on each file, file, but then if the
pipe succeeds (which in fact means just whether xargs exits with 0) it
just tries to remove `{}'.

You may need to invoke the shell explicitly to get the  behaviour,
eg
  find  | xargs -n 1 sh -c 'dpkg-split -s {}  rm {}'

Ian.


Re: find question (and xargs)

1996-05-16 Thread Richard Kettlewell
find / -size +459976c -noleaf -type f -name '*.deb'|\
xargs -n 1 dpkg-split -s {}  rm {}

I was thinking that {} would be replaced by the filename but that's
not the case. Anyone know how to solve this?

It's find that does the replacing. None of the {}s are in the find  
arguments, however. (And rm is not even in the xargs arguments!)

Using `xargs -i' will substitute for {}.

To get  right, put quotes round it.

Personally, I'd probably make a script for the split-and-remove, but it  
should also work with a shell function.

Doesn't work for me, nor did I expect it to.

ttfn/rjk


Re: find question (and xargs)

1996-05-15 Thread Kai Henningsen
[EMAIL PROTECTED] (Erick Branderhorst)  wrote on 13.05.96 in [EMAIL 
PROTECTED]:

 find / -size +459976c -noleaf -type f -name '*.deb'|\
 xargs -n 1 dpkg-split -s {}  rm {}

 I was thinking that {} would be replaced by the filename but that's
 not the case. Anyone know how to solve this?

It's find that does the replacing. None of the {}s are in the find  
arguments, however. (And rm is not even in the xargs arguments!)

Personally, I'd probably make a script for the split-and-remove, but it  
should also work with a shell function.

Anyway, I'd probably try something like this:

find / -size +459976c -noleaf -type f -name '*.deb' -exec split.sh {} \;

#! /bin/sh
dpkg-split -s $1  rm $1



MfG Kai


Re: find question (and xargs)

1996-05-15 Thread Craig Sanders

On 14 May 1996, Kai Henningsen wrote:

 It's find that does the replacing. None of the {}s are in the find
 arguments, however. (And rm is not even in the xargs arguments!)

 Personally, I'd probably make a script for the split-and-remove, but
 it should also work with a shell function.

A function probably wont work - without some overly complicated tricks,
a shell function is only available within the context/scope of the shell
or shell script which defines it.  Programs forked by that shell or
shell script can't exec it because it's not a program as far as they're
concerned.

This seems weird and possibly counter-intuitive, but it does make sense.

It can produce some very unexpected behaviour if you're not used to
it. 

My rule of thumb is to only use functions within the context of a
specific shell script, and not to expect them to be available in
sub-shells or shell scripts where they haven't been explicitly defined.
Of course, i could start all shell scripts with something like source
~/myfuncs.sh but that would be overkill (and ugly!).


 Anyway, I'd probably try something like this:
 
 find / -size +459976c -noleaf -type f -name '*.deb' -exec split.sh {} \;
 
 #! /bin/sh
 dpkg-split -s $1  rm $1

if you're going to write a script, it's faster to use xargs, that way
the script only needs to be forked once.


find / -size +459976c -noleaf -type f -name '*.deb' | xargs split.sh 

#! /bin/bash
for pkg in $@ ; do 
  dpkg-split -s $pkg  rm $pkg
done


split.sh could even be written to take a list of files on stdin and process
them accordingly.  more effort than what it's worth IMO, let xargs do the
job :-)

Craig


Re: find question (and xargs)

1996-05-14 Thread J.H.M.Dassen
 I have come at the following but it doesn't work (and can't figger 
 out why not from the manpages).
 
 find / -size +459976c -noleaf -type f -name '*.deb'|\
 xargs -n 1 dpkg-split -s {}  rm {}
 
 I was thinking that {} would be replaced by the filename but that's
 not the case. Anyone know how to solve this?

The {} substitution happens only in a -exec argument; 
you're using it after the find command.

Try find / -size +459976c -noleaf -type f -name '*.deb' -exec \
  dpkg-split -s {}  rm {}

Ray


Re: find question (and xargs)

1996-05-14 Thread Jan Wender
Hi all,

this might be a more unix oriented question but I'll ask it anyway
because it is very debian related too:

I would like to find packages bigger than 459976 bytes and split them
with dpkg-split, if splitting is succesfull I'll remove the package.
I have come at the following but it doesn't work (and can't figger
out why not from the manpages).

find / -size +459976c -noleaf -type f -name '*.deb'|\
xargs -n 1 dpkg-split -s {}  rm {}

I was thinking that {} would be replaced by the filename but that's
not the case. Anyone know how to solve this?
Basically this is right, the {}'s get converted to the file name in
*find's argument list*. The arg list is ended at the |, because then
a new program is started.
Possible Solution:
use find's exec option:
find / -size +459976c -noleaf -type f -name '*.deb' -exec dpkg-split -s {} \
-exec rm {}
Be careful to quote the {{}'s appropriately, or the shell may munge them
into something different.
A more efficient solution would be to write a small perl program along the
lines:
sub dodir {
  my ($dir) = shift;
  opendir DIR, $dir;
  while (readdir(DIR)) {
maybesplit if -f;
dodir($_) if -d;
  }
  closedir(DIR);
}
dodir($ARGV[1]);
--
Cheerio, Jan
Jan Wender - [EMAIL PROTECTED] - Universitaet Trier, Germany
Linux is the choice of a Gnu.
The man who letterspaces lowercase letters also steals sheep (F. Goudy)


Re: find question (and xargs)

1996-05-14 Thread joost witteveen
 
 Hi all,
 
 this might be a more unix oriented question but I'll ask it anyway 
 because it is very debian related too:
 
 I would like to find packages bigger than 459976 bytes and split them
 with dpkg-split, if splitting is succesfull I'll remove the package.
 I have come at the following but it doesn't work (and can't figger 
 out why not from the manpages).
 
 find / -size +459976c -noleaf -type f -name '*.deb'|\
 xargs -n 1 dpkg-split -s {}  rm {}

How is xargs to know what {} stands for? {} works in the -exec
part in find, not for xargs.

Probably what you want is:

 find / -size +459976c -noleaf -type f -name '*.deb' \
-exec sh -c dpkg-split -s {}  rm {} \;

-- 
joost witteveen
[EMAIL PROTECTED]
  [EMAIL PROTECTED]
--
Use Debian Linux!


Re: find question (and xargs)

1996-05-14 Thread Erick Branderhorst

Hi users,

I found the solution (with help from Steve Preston, Kenvin Dalley,
Ray Dassen and Jan Wender).

now I use the following:
find /home/ftp/pub/debian -size +459976c -noleaf -type f -name '*.deb'| \
xargs -l -i sh -c dpkg --info {} /dev/null  dpkg-split -s {}  rm {}

This gives a lot of evil messages about packages not being a debian
archive because they are the splitted archives of a previous run and 
not all splitted archives are exactly 459976 or smaller (unfortunately).

I use the dpkg --info command to test whether it is a package.

Erick
 
--
Erick [EMAIL PROTECTED] +31-10-4635142
Department of General Surgery (Intensive Care) University Hospital Rotterdam NL


Re: find question (and xargs)

1996-05-14 Thread Brian C. White
 find / -size +459976c -noleaf -type f -name '*.deb'|\
 xargs -n 1 dpkg-split -s {}  rm {}
 
 I was thinking that {} would be replaced by the filename but that's
 not the case. Anyone know how to solve this?

Find only replaces {} with the filename under -exec.  You have piped
the output of the implicit -print command into 'xargs'.  You must either
use xargs' substitution method:

find / -size +459976c -noleaf -type f -name '*.deb' |\
xargs -n 1 -i{} dpkg-split -s {}  rm {}   # I think...

or change find:

find / -size +459976c -noleaf -type f -name '*.deb' \
-exec dpkg-split -s {}  rm {} \;

Brian
   ( [EMAIL PROTECTED] )

---
In theory, theory and practice are the same.  In practice, they're not.


Re: find question (and xargs)

1996-05-14 Thread Guy Maor
On Mon, 13 May 1996, Erick Branderhorst wrote:

 find / -size +459976c -noleaf -type f -name '*.deb'|\
 xargs -n 1 dpkg-split -s {}  rm {}
 
 I was thinking that {} would be replaced by the filename but that's
 not the case. Anyone know how to solve this?

Two mistakes and an admonition:
You need to give -i to xargs to use the {} syntax.
You need to escape the  so that the rm will be part of the command.
For safety, you should always use -print0, -0 with find and xargs.

So do this instead:
find / -size +459976c -noleaf -type f -name '*.deb' -print0 |\
xargs -0 -n 1 -i dpkg-split -s {} \\ rm {}



Guy