Main problem with extra commands is that there are more to
learn. Redundancy like this basically pollutes the namespace
and makes things much harder to learn. In other words more
than one (equivalent) way to do something is bad.

This is equivalent to the difference between the windows
and UNIX APIs. UNIX is narrow and general, whereas windows is
broad and specialised. So IMHO we should always be trying to
refactor everything into cohesive units with narrow/general interfaces. 

Obviously you can't throw away existing utilities, for backwards compatability
reasons, but you can provide mappings, and also encourage the use of the more 
general tools. The mappings can be done with aliases/scripts/or checking
of argv[0] (the command name). While we're taking about argv[0] handling,
it seems obvious that the commands below should be in 1 file with links
    sleep,usleep (sleep=sh-utils, usleep=initscripts)
However it's gnu policy to split even these up into seperate
files, rather than link them. The reason given is that users may 
want to copy them to different names. However this is trivally supported 
using doexec. For e.g. if you wanted to link mygrep to egrep, then just:
alias mygrep='doexec mygrep egrep'

While were talking about grep, notice that the functionality
is a subset of sed (or should be). The hard thing to learn is the regular 
expressions (more on these later), so just having to know 1 (sed) interface
would be an advantage. Here's an e.g. of a trivial script using sed to show
how easy it is to add highlighting functionality to "grep":


For backwards compatability as mentioned above, the the grep and sed programs 
should be (links to) the same executable, with slightly different internal 
processing depending on argv[0].

This table illustrates some more possibly redundant commands and alternatives.

hexdump od -Ax -tx1z -v
head sed 10q
grep expr sed -n /expr/p
unix2dos sed /$/^M/
dos2unix tr -d '\r'
expr is a subset of bc
expand pr -T -e or sed s/.../.../
unexpand pr -T -i or sed s/.../.../
tr could be incorporated in dd
clear tput clear (etc)
gunzip gzip -d
bunzip2 bzip2 -d
basename tr -s '/' | sed -e 's|/$||' | sed -e 's|.*/\([^/]*\)$|\1|'
dirname tr -s '/' | sed -e 's|/$||' | sed -e 's|/[^/]*$||'
true exit 0
false exit 1
tar -z same as just | gzip
tar -i same as just | bzip2
tar -Z same as just | compress
tar --use-compress-program PROG same as just | PROG
z{less,more} redundant as less auto handles with
Note also apps that need this functionality can use gzopen from zlib,
or the method, so all the z... commands and probably redundant.
An e.g. of the above: alias hd="od -Ax -tx1z -v" hd /etc/fstab hd /etc/fstab | ./sedgrep "[0-9][a-f]" In general in Unix there is not much code reuse (especially server programs) probably since there were disparate Unix' until recently and the only common denominator usable was libc. This is getting better now with language independent interfaces to logic like bonobo and mono. Note M$ is way better in this regard. Note pipes are very useful, but not a silver bullet. For e.g. data flow is one way only, also there is no type checking, or ways to dynamically determine what kind of data the sink expects... Also take the example of the standard text utilities (cut,sort,uniq). These are inherently record/field based. I.E. they work at a higher level with the data, rather than a stream of bytes. However they use different methods to specify fields, field seperators and record seperators (\n,\0,...). For e.g. uniq can only say skip the first X fields, whereas sort has a powerful key selection mechanism which would be very useful. Also these could easily share the same code, making them all simpler and more powerful. (p.s. I'm currently working on a patch to do this).