svn commit: r247274 - in head: bin/test tools/regression/bin/test

Chris Rees utisoft at gmail.com
Fri Mar 1 17:13:51 UTC 2013


On 1 Mar 2013 14:27, "Jilles Tjoelker" <jilles at stack.nl> wrote:
>
> On Wed, Feb 27, 2013 at 07:25:48PM +1100, Peter Jeremy wrote:
> > On 2013-Feb-26 01:02:27 +0100, Jilles Tjoelker <jilles at stack.nl> wrote:
> > >>   Enhance test(1) by adding provision to compare any combination of
the
> > >>   access, birth, change and modify times of two files, instead of
only
> > >>   being able to compare modify times.  The builtin test in sh(1) will
> > >>   automagically acquire the same expansion.
>
> > >What do you need this for? If it is not needed very often, this test
can
> > >be done more portably (older FreeBSD and GNU) as
> > >  [ -n "$(find -L FILE1 -prune -newerXY FILE2 2>/dev/null)" ]
>
> > In my case I needed to compare the ctime on one set of files with the
> > mtime in another set.  I had a think about using find(1) and gave it
> > away as too ugly.  That expression needs serious thought to understand
> > and about ½ the tokens in the find(1) are to handle special cases -
> > which is a further indication that it isn't ideal.
>
> Making everything ideal out of the box is not possible; it would bloat
> up things too much and make scripts harder to read. There are many
> possible extensions to avoid problems with special cases that would be
> useful more frequently, such as arrays, ${PARAM/WORD/REPLACEMENT},
> ${PARAM:START:LENGTH} and optional more useful signal handling.
>
> And I don't think this case is particularly bad. By defining the below
> function
>
> file_newer() {
>         test -n "$(find -L -- "$2" -prune -newer$1$3 "$4" 2>/dev/null)"
> }
>
> you can do things like  file_newer m file1 c file2  to compare file1's
> mtime to file2's ctime. The ugliness is isolated to the function
> definition.
>
> The birth time is designated by B instead of b. This is because find(1)
> wants B, and so does stat(1).
>
> Furthermore, it also allows  file_newer m file1 t '2 days ago'  to
> compare to a specified time; however, only the second time can be 't'.
>
> It is also possible to query file times using stat(1). This allows
> intuitive constructions like
>   [ $(stat -f %m FILE1) -gt $(stat -f %c FILE2) ]
> lets you compare to things like  $(($(date +%s) - 86400))  and allows
> control whether symlinks should be followed. However, this may fork more
> often than the find(1)-based approach and hard-codes the limitation to
> seconds into the script unless you do something more complicated like
>   [ $(stat -f %040.9Fm FILE1) \> $(stat -f %040.9Fc FILE2) ]
> The test(1) syntax will also be incorrect if the files do not exist.
>
> The find(1) and stat(1) approaches also work in other shells such as
> bash, ksh and zsh. An extension to test(1) can only be used by writing
> ugly things like /bin/test. Whatever you may think of it, people write
> scripts for those other shells and it is somewhat unfortunate that they
> cannot use all FreeBSD-specific features.

+1

While I'm aware that we have many very useful extensions to sh, we should
not sacrifice portability.

We (porters) are on thin ground when complaining at upstream for assuming
/bin/sh is bash when we have extensions such as these.

Chris


More information about the svn-src-all mailing list