Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Hi all, author here. I'm not sure of the rules around self promotion so I want to point out that I didn't submit this, but I'm happy to see that others are enjoying it.

I wrote this blog post to document my process of building a simple shell using Rust. I learned a lot about how shells, terminal emulators, and the OS interact by going through this exercise, so I hope this is useful to others as well.

Feel free to reach out if you have any questions.



For future reference, it's fine to submit your own stuff as long as you don't overdo it. For things that can be tried out, there's also a special Show HN category: https://news.ycombinator.com/show


Tooting your own horn is a foundational block of HN and very welcome!


If you have open source projects, then I would like to join


I've linked my GitHub profile below. I really enjoy social coding, so feel free to open pull requests or issues on any of my repos.

https://github.com/JoshMcguigan


I've never used Rust, but looking at the code, and reading https://doc.rust-lang.org/std/process/struct.Command.html , is std::process:Command just farming out to bash? I ask, because the examples don't specify a full path, so that implies something else is doing the PATH search, like bash. Because of this, and the semantics, it looks like it's equivalent to a system() function in other languages.

If you really want job control, a path, environmental variables, and all the things that make a shell a shell, you have to be using exec() or execvp() https://doc.rust-lang.org/std/process/struct.Command.html#me... . Otherwise all you've done is wrap an existing shell that does all the work for you, and that was an immediate fail when we had to a make a shell in my undergrad systems course.

An easy check is the use the command "echo $SHELL". If that spits out anything besides literally "$SHELL", you're farming out.

All that said, Rust's exec() is listed a unix specific, so if you're on Windows, I guess you're stuck.


I'm not confident enough to say this for sure, but I think you are off base.

I created a demo in the Rust playground [0] which shows that there is no implicit environment variable expansion. Also, the source for `std::process:Command` [1] looks to be calling into libc to perform a fork/exec.

That said, this is rather new territory for me, so let me know if I'm missing something here.

[0] : https://play.rust-lang.org/?version=stable&mode=debug&editio... [1] : https://github.com/rust-lang/rust/blob/master/src/libstd/sys...


It will use `execvp` (which automatically reads the PATH variable, no shell required) if you use features that require it (like `before_exec` which runs a block of code between `fork` and `exec), but it generally prefers `posix_spawnp` (Which also uses PATH). The relevant code is here: https://github.com/rust-lang/rust/blob/7d3b9b1640611c52eb949....

All of this is of course Unix specific, on Windows it uses `CreateProcess`.


If you or anyone else would like to file a bug, that’d be great: we should make this more clear in the docs. I’m about to jump on a plane or I’d just do it; a bug will make sure I get back around to it eventually.


Why would the docs need to be updated? Is it assumed that a command would be executing a bash or other shell process?


If something isn’t clear, it deserves an update.

This could be by adding some text to clarify that this doesn’t use a shell, or maybe changing the examples to not imply one is used. It just depends.


The internal implementation of Command is using libc::execvp() on unix and CreateProcessW on windows. In windows case, it's searching the executable in the PATH manually first to match the semantics of unix.


If you look at the examples in the first link you posted, you can see to farm out to an existing shell, they're explicitly invoking "sh". There would be no reason to do that if Command always farmed out to another shell.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: