Decoded: GNU Coreutils (2018)
maizure.org
maizure.org
"They are not designed for long life or to scale beyond their role."
Would love to see some examples from the author of programs he believes are "designed for long life" that have been around 30 years.
Or even ones he thinks will be around for 30 years.
To test a little programming language I made, I created a testing framework with bash and coreutils. I felt guilty about not using a "proper" language at first but it works so well. In parallel too.
I found that the the only thing I couldn't test was the argv[0] of the program. No matter how much I twisted the programs, I couldn't get them to do exactly what I wanted. So I sent a feature request and a patch to coreutils to give env this feature:
https://lists.gnu.org/archive/html/coreutils/2023-08/msg0006...
Looks like it's gonna make it in. A new feature for this old program.
# Sets PWD and SHLVL and the latter apparently can't be unset
env -i VARIABLE=value bash -c 'exec -a program ./program'
# Sets env's argv0, not my program's
bash -c 'exec -a program env -i VARIABLE=value ./program'
# SHLVL still set
env -i bash -c 'unset SHLVL; unset PWD; exec -a program ./program'
# SHLVL and _ still set
env -i zsh -c 'unset _ HOME PWD LOGNAME SHLVL OLDPWD; ARGV0=program
The original discussions, linked from my post:https://lists.gnu.org/archive/html/coreutils/2023-03/msg0000...
https://lists.gnu.org/archive/html/coreutils/2023-03/msg0001...
Here's the code if you wish to take a look:
https://github.com/lone-lang/lone#testing
https://github.com/lone-lang/lone/blob/master/scripts/test.b...
Without env -i, the folllowing tests would not be possible:
https://github.com/lone-lang/lone/blob/master/test/linux/env...
https://github.com/lone-lang/lone/blob/master/test/linux/env...
https://github.com/lone-lang/lone/blob/master/test/linux/env...
--argv0 STRING set argv[0] to STRING before running
Maybe that could be useful?/lib64/ld-linux-x86-64.so.2 --argv0 argv0isalie yourprogramm
ld is the (not dynamic) linker. It doesn't invoke your program at all.
Like in years down the line, maybe as you retire and hang up your keyboard, you could sit back and smile as you realise your code is still deployed on millions, possibly billions of devices? That the code could far outlast 99.9% of code code anyone has ever written?
I can't deny I'm gonna be really happy if they do use it.
* How the GNU coreutils are tested: https://www.pixelbeat.org/docs/coreutils-testing.html
* Exploration of each of the coreutils commands: https://ratfactor.com/slackware/pkgblog/coreutils
* Command line text processing with GNU Coreutils: https://learnbyexample.github.io/cli_text_processing_coreuti... (my ebook that covers 20+ text processing tools)
Decoded: GNU Coreutils (2018) - https://news.ycombinator.com/item?id=29871037 - Jan 2022 (7 comments)
Decoded: GNU coreutils (2019) - https://news.ycombinator.com/item?id=26411908 - March 2021 (38 comments)
Decoded: GNU Coreutils - https://news.ycombinator.com/item?id=20328650 - July 2019 (55 comments)
[0]: https://maizure.org/projects/decoded-gnu-coreutils/shred.htm... [1]: https://maizure.org/projects/decoded-gnu-coreutils/csplit.ht...
package main
import "flag"
func main() {
yes := flag.String("m", "y", "message")
flag.Parse()
for {
println(*yes)
}
} ++++++++++[->++++++++++++>+<<]>+[.>.<]
(Unfortunately, Brainfuck doesn't support command line flags.)https://www.reddit.com/r/unix/comments/6gxduc/how_is_gnu_yes...
yes Go lines of code: 9
main(int argc, char** argv) {
while (1) {
if (argc > 1)
for (int i = 1; i < argc; i++) printf("%s%c", argv[i], (i == argc - 1) ? '\n' : ' ');
else puts("y");
}
}
The point other folks are making is that it's written differently for a reason. Maybe not a reason that's important, but at the very least, let's try to compare apples to apples.You could argue about the loop itself, after all K&R specified "for(;;)", but the other commonly used (ergo idiomatic) infinite loops use precisely the same number of lines. "while(1)" is a perfectly idiomatic manner to create an infinite loop.
Likewise a void return type for main was entirely legal until C99. The BSD yes(1) I've laying around only prints the first argument, so flag parsing? What flag parsing?
Yes in nine lines of C inclusive of preprocessor macro invocations and white space.
#include <stdio.h>
int main(int argc, char **argv) {
const char *phrase = argc > 1 ? argv[1] : "y";
while (1) {
printf("%s\n", phrase);
}
return 0;
}If it's more comfortable you can also declare argv as an array of character arrays e.g. char *[], but that won't change the line count.
the Go code has MORE functionality (flag parsing) with LESS code. yes its not as fast, and yes the executable is larger, but for many, thats a good tradeoff for the extra standard library features, and the reduced LOC/code complexity. sadly as of yet, I haven't seen any cogent technical arguments against my points thus far.
I'm genuinely curious to hear your argument.
previous comments have demonstrated this not to be the case, so I will stand by my previous points. I have already made over 10 comments on this one topic, so if any aren't already convinced, they never will be, either because they disagree with the tradeoff, or they just have stockholm syndrome for C.
https://github.com/openbsd/src/blob/master/usr.bin/yes/yes.c
Your code does not have more functionality than GNU's yes as written. It's less code you have to write because of the flag parsing code that has already been written, and it's incompatible with GNU's yes because yours requires -m to change the message.
it has flag parsing
That's the whole point. Every single command line program needs command line parsing. Go helps me get the job done, C forces me to write my own parser, or find some third party one.
The 10x LOC (despite being a huge exaggeration) is also the fixed cost, not the marginal cost. You're only forging main loop and includes, not any fundamental complexity.
This is also a funny argument coming from a Go programmer considering that Go trades off conciseness and expressivity for simplicity. Show me some of your favorite Go and I'm sure we can replace it with some concise C++.
I just physically shuddered
In fact, most embedded Linux thingy will be running the busybox version of core utilities instead of gnu coreutils for binary size reasons.
I other words, even gnu coreutils is too big.
It's pretty easy to avoid this problem anyway - just combine multiple tools into one binary like Busybox does.
In any case the simplicity of the Go code is not really related to the binary size.
With modern systems we can have 8 channel RAM and 128 PCIe lanes to feed a system stuffed with NVMe drives. The amount of throughput that can be obtained is nuts, and at that point all sorts of weird things can become an unexpected bottleneck.
This applies even in consumer systems. Suddenly your game loads far slower on a NVMe than it could because it never occurred to the programmer that instead of the disk, the JPEG decoder can become a bottleneck when you can read compressed data at 7 GB/s.
But for 'yes', I'd agree with you, though I guess the answer to "who cares?" is that whomever wrote it cared. They could have a legit performance reason or may just have done it to show they could.
* The fast version is still simple enough
* The general functionality being provided is to output arbitrary data repeatedly, and it can be useful to do this as fast as possible
https://news.ycombinator.com/item?id=27862463
I think this person is just mentally ill unfortunately.
My point was in part that it's valuable for even a simple utility to be well written and optimized and that it's nice to have these minimal examples to learn about how to, e.g. write output very quickly. The program is so short that presumably the number of lines is unimportant, and if the author knows how to do it they might as well make it as fast as possible so it's never in the way, and so we can learn from it. That's why I think it's a good example.
https://github.com/openbsd/src/blob/master/usr.bin/yes/yes.c https://github.com/freebsd/freebsd-src/blob/release/4.0.0/us...
sudo find / -type f -exec shred {} \;
to see how far it gets before killing itself (on a VM or easily re-flashed machine of course).What am I missing?
Essentially, a file can have 0 or more names linked to it. As long as a file has at least one name or at least one process with it open, it will persevere.
By contrast, shred actually writes to the underlying file.
I did this, but with dd -- it completed. Was very anti-climatic. I was hoping it would crash or at least disconnect me, but the kernel, sshd and bash were still in memory and happily returned me to a prompt where I couldn't really do anything.
However, I find it interesting that true and false use the very same implementation.
first an exercise
touch mytrue
chmod u+x mytrue
./mytrue
echo "error code for mytrue is $?"
This is literally how true started life. yes it is very zen.The first offense was legal. All code had to have a copyright disclaimer. even an empty file? Yes. so now it was a file with a copyright disclaimer and nothing else. And the koan-like question comes to mind is "Can you copyright nothing?" well AT&T sure tried.
Then somebody said our programs should be well defined and not depend on a fluke of unix, which at this point was probably a good idea. So true finally had code. It was "exit 0"
Then somebody said we should write our system utilities in C instead of shell so it runs faster. openbsd still has a good example of how this would look.
http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/usr....
At some point gnu bureaucracy got involved and said all programs must support the '-h' flag. so that got added, then they said all programs must support locale so that got added. now days gnu true is an astonishing 80 lines long.
https://github.com/coreutils/coreutils/blob/master/src/true....
Which is fine I guess, but that is a lot of code for a program that by definition "Does nothing, successfully"
It's more a software engineering endeavour instead of computer science.
Stick to busybox commands as much as you can.
And from the first thing you learn in real life, is humility, but sometimes, some people makes you feel you know everything, like here... but I very well know I am average/normal, which worsen even more his/her case. Yeah, a bit like John Snow.
This is an horrible feeling.
Not to mention, this post is border-line passive-aggressive... so...
what's this ???
Let's presume this is a chatgpt troll.