[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: md5sum and recursive traversal of dirs
From: |
Kaz Kylheku (Coreutils) |
Subject: |
Re: md5sum and recursive traversal of dirs |
Date: |
Thu, 10 Oct 2019 12:23:42 -0700 |
User-agent: |
Roundcube Webmail/0.9.2 |
On 2019-10-10 10:29, Сергей Кузнецов wrote:
Hello, I find it strange that md5sum does not yet support recursive
directory traversal. I moved part of the code from ls and added this
functionality. How about adding this? I also added sha3 and md6
algorithms,
they are in "gl/lib/".
If we have any utility whatsoever that operates on files, sometimes
we want to apply it to every file in a tree.
It does not follow that every utility whatsoever that operates on files
should integrate the code for traversing a tree.
We have ways in the shell, and in other programming languages, to
map any operation over a tree of files.
The mapping mechanism maps, the MD5 mechanism calculates MD5 sums;
each has a single responsibility.
One noteworthy tree traversal mechanism appears as an extension in the
GNU Bourne-Again Shell (Bash). In Bash, if you set the "globstar" option
like this:
shopt -s globstar'
If this is enabled, then the ** operator becomes active in file globbing
patterns. The ** operator spans across multiple path components. For
instance:
# calculate the md5sums of all .so files anywhere in /usr/lib
md5sum /usr/lib/**/*.s
By the way, I wrote two new small programs: xchg (or swap, which name
is
better?) And exst (exit status).
Exchanging two files can be implemented as a shell function, which can
be
extremely simple if we don't worry about exchanging files in different
filesystem volumes. Here is a sketch:
swap()
{
local tmpname=$(mktemp swap-XXXXXX)
# ... check arguments here for count and sanity ...
mv -- "$1" $tmpname
mv -- "$2" "$1"
mv -- $tmpname "$2"
}
The first program simply changes files,
the number of which can be more than two.
That should proably be called "rotate", like the rotatef operator in
Common Lisp. The logic becomes something like (untested):
# if we have at least two arguments:
if [ $# -gt 1 ] ; then
mv -- "$1" $tmpname
# while we have two or more arguments
while [ $# -gt 1 ] ; do
mv -- "$2" "$1"
shift
done
# last argument gets $tmpname
mv -- $tmpname "$1"
fi
Example: rotate some logs:
rotate deleteme log.2 log.1 log.o log
rm deleteme
Undoubtedly elegant and useful; but should it be a C program in GNU
Coreutils? Hardly.
The second program launches the
program indicated at startup and, after its completion, prints the
output
status or the caught signal.
Doable in shell scripting, again. The status of the last command is
available
in the $? variable. This can be tested:
stat=$?
if [ $(( stat & 0x80 )) != 0 ] ; then
printf "terminated due to signal %d\n" $((stat & 0x7F))
else
printf "exited with status %d\n" $stat
fi
Bash has "massaged" the value already. That is to say, if the program
terminates normally with an unsuccessful status 19 we don't have to do
any shifting to recover the value from the upper bits of an exit status
word; $? simply holds the value 19.