GNU userland is of poor quality
gist.github.com
gist.github.com
Also, if you actually read the code it's the --help that takes up most lines in GNU's case. That's probably a standard inside coreutils codebase.
GNU echo simply does a lot more than the other echo implementations. And believe me it's much more useful in daily usage. That's why the GNU tools are so successful. All the minimal (often broken) utilities you had to use on commercial Unices were no fun. So everybody installed the GNU stuff.
I use -e and -n options of GNU echo regularly. Even if
echo "foo\nbar" | remove-trailing-space | expand-escape-sequence
would be the "UNIX way" of doing it.The only thing of poor quality here is the submission title!
"Quality" is in the eye of the beholder. Some people might like the extra features and in the usage documentation built into the GNU product. Other people hate every excess line of code that they need to maintain.
Another part of the reason is that GNU code, historically, tried on purpose to look different at the source code level from other Unix systems, to reduce the possibility of accusations of illegal copying.
1) It reduces the number of syscalls -- a single call to writev outputs everything, rather than multiple fputs calls which may or may not be buffered (I haven't checked the impl details of fputs).
2) It reduces the number of allocations. Since an iovec is just an array of pointers, we can reused the data passed in via argv; the length of the iovec is capped at argc, so we can get away with one allocation without scanning the input.
For a comparison, here's a brief overview of each of the implementations (assuming fprint/fputs is not buffered):
* Unix V5: 0 allocations, N syscalls, no argv scan
* OpenBSD: 0 allocations, N syscalls, no argv scan
* Plan 9: 1 allocation, 1 syscall, scans argv
* FreeBSD: 1 allocation, 1 syscall, no argv scan
* GNU (without -e): 0 allocations, N syscalls, no argv scan
"argv scan" basically means calling strlen on every passed argument, or otherwise iterating over them. Naturally, "which one is faster" depends on how fast your allocations/syscalls/strlen's are, and how fprint/fputs is buffered.
GNU relies on stdio's buffering for this. Plan 9 allocates a buffer for the entire output and copies the arguments there. FreeBSD wants to avoid linking to stdio, and wants to avoid copying memory (both for reasons of efficiency, presumably), so it uses the writev call instead, which lets you pass the kernel an array of buffers to write, without having to build up a single buffer in advance.
When working on Solaris or OS X, one of the first things I do is get the GNU utilities into my path ahead of native ones. That way, I get the same environment on all 4 platforms I use - Cygwin, Linux, OS X and Solaris.
echo --version vs /bin/echo --version
What I can't understand is the terrible malloc() implementation in glibc still being there after all these years.
Now you can't lead off like that and not tell us what is so bad about it, and what I should use instead!
Among the many problems with glibc's malloc (when I tested, anyway) is that it slows down considerably as soon as you start up a thread, even if you immediately shut it down.
There seems to be some kind of computer nerd pecking order, similar to the "Trekkie->Larper->Furry" sequence. Lispers->Smalltalkers->Linuxers->9fans? (With Niklaus Wirth standing on the sideline, shaking his head)
Use printf(1) instead.
That comment nails it.