Live data from Hacker News

Pnut: A C to POSIX shell compiler you can trust

pnut.sh

31–40 of 124 posts

Re: Pnut: A C to POSIX shell compiler you can trust

#32

Hrmmm. But why? Quite frankly I think Bash scripting is awful and frequently wish shell scripts were written in a real and debuggable language. For anything non-trivial that is. I feel like I’d rather write C and compile it with Cosmopolitan C to give me a cross-platform binary than this. Neat project. Definitely clever. But it’s headed in the opposite direction from what I’d prefer...

I don't know about the specific motivations for this project, but if you're curious about why work like this might have serious real-world relevance beyond scratching an itch, idle exploration, or meeting a research paper quota, you can look to similar work and literature:

GNU Mes: https://www.gnu.org/software/mes/

Stage0: https://bootstrapping.miraheze.org/wiki/Stage0

Ribbit (same authors): https://github.com/udem-dlteam/ribbit

stage0-posix: https://github.com/oriansj/stage0-posix

Bootstrappable Builds: https://bootstrappable.org/

See also this LWN article about bootstrappable and reproducible builds: https://lwn.net/Articles/841797/ It contains a plethora of interesting links.

Re: Pnut: A C to POSIX shell compiler you can trust

#34

Earlier quoted context omitted.

One of the example we include is a base64 encoder/decoder: https://github.com/udem-dlteam/pnut/blob/main/examples/compiled/base64.sh It doesn't support NULs as you pointed out, but it's interesting to see similarities between your implementation and the one generated by Pnut. Because we use `read -r`, we haven't tested reading binary files. Fortunately, the shell's `printf` function can emit all 256 characters so Pnu…

Sorry, but since the very goal of base64 is to encode "uncomfortable" bytes, saying that your example doesn't work with uncomfortable bytes is like providing a fibonacci demo that only works with arguments less than 3, or a clock that only shows correct time twice a day. I'd choose a different example to showcase pnut.

In the context of what it seems to be primarily attempting to achieve, assisting in the bootstrapping of more complex environments directly or indirectly dependent on C, I found the base64 example (more so the SHA-256 example in the same directory) quite interesting and evidence of the sophistication of pnut notwithstanding the limitations. And as was pointed out, it wouldn't be difficult to hack in the ability to read binary data: just swap in a replacement for the getchar routine, such as I've done with od. In fact, that ease is one of the most fascinating aspects of this project--they've built a conceptually powerful execution model for the shell that can be directly targeted when compiling C code, as opposed to indirection through an intermediate VM (e.g. a P-code interpreter in shell). It has it's limitations, but those can be addressed. Given the constraints, the foundation is substantial and powerful even from a utilitarian perspective.

When people discuss Turing completeness and related concepts one of the unstated caveats is that neither the concept itself, nor most solutions or environments, meaningfully address the problem of I/O with the external environment. pnut is kind of exceptional in this regard, even with the limitations.

Re: Pnut: A C to POSIX shell compiler you can trust

#35
post #6

I was puzzled by the example C function containing pointers. Do I understand correctly that you implement pointers in shell by having a shell variable _0 for the first "byte" of "memory", a shell variable _1 for the second, etc.?

Author here, That's correct! Unlike Bash and other modern shells, the POSIX standard doesn't include arrays or any other data structures. The way we found around this limitation is to use arithmetic expansion and indexed shell variables (that are starting with `_` as you noted) to get random memory access.

I used almost the same idea, but with files in my https://github.com/steveschnepp/shlibs

Re: Pnut: A C to POSIX shell compiler you can trust

#36
post #19

If you are wondering how it handles C-only functions.. it does not. open(..., O_RDWR | O_EXCL) -> runtime error, "echo "Unknow file mode" ; exit 1" lseek(fd, 1, SEEK_HOLE); -> invalid code (uses undefined _lseek) socket(AF_UNIX, SOCK_STREAM, 0); -> same (uses undefined _socket) looking closer at "cp" and "cat" examples, write() call does not handle errors at all. Forget about partial writes, it does not even return -…

Implementation issues aside, while technically it should be possible to seek a file descriptor from shell through a suitable helper program in C, I believe none of the POSIX utilities provide this facility

head, read, and sed can be used for seeking forward according to POSIX (see the INPUT FILES section here https://pubs.opengroup.org/onlinepubs/9799919799/utilities/V...>). I doubt non-GNU implementations support it though.

Re: Pnut: A C to POSIX shell compiler you can trust

#37
post #26

Earlier quoted context omitted.

Master Foo long predates Python and Rust.

Masters live to be surpassed by their students. Just because something was best in class in the 80s doesn't mean it should still be used.

Very true, but also student hubris is legendary. Which is perfectly fine, as we all know successful students.

But let's not blind ourselves with the survivor bias. Not everything new and very bright will succeed the test of time.

So let's take evrything with a grain of salt, and wait until the time has choosen its champions. Which might not be the best technology as we learned

Re: Pnut: A C to POSIX shell compiler you can trust

#38

Hrmmm. But why? Quite frankly I think Bash scripting is awful and frequently wish shell scripts were written in a real and debuggable language. For anything non-trivial that is. I feel like I’d rather write C and compile it with Cosmopolitan C to give me a cross-platform binary than this. Neat project. Definitely clever. But it’s headed in the opposite direction from what I’d prefer...

> Hrmmm. But why?

because Bash goes brrrr

Re: Pnut: A C to POSIX shell compiler you can trust

#40

Earlier quoted context omitted.

Shell is just one way. There’s nothing that says we can’t do better than shell, but what it’s good at is saving programmer time when the need isn’t there for more, and Rust is definitely not good at that.

My rule of thumb: Shell: 500 lines Although to be honest I'd be perfectly happy if Shell was restricted to single line commands only. I've wasted a lot of time and energy deciphering undebuggable shell scripts that were written to "save programmer time". Not a fan.

This rule of thumb is clearly too simplified, even as far as the definition goes.

Sometimes you just want to execute 50 lines with little logic.

Sometimes you just have some simple logic that needs to be repeated.

Sometimes that logic is complicated, sometimes it is not.

Post reply on HN