[Rust] Stuck on stage #ei0

I’m stuck on Stage #ei0.

Here are my logs:

remote: ------------------------------------------------------------------------
remote: 
remote: 
remote:      ___            _          ___              __  _                   
remote:     / __\ ___    __| |  ___   / __\_ __  __ _  / _|| |_  ___  _ __  ___ 
remote:    / /   / _ \  / _` | / _ \ / /  | '__|/ _` || |_ | __|/ _ \| '__|/ __|
remote:   / /___| (_) || (_| ||  __// /___| |  | (_| ||  _|| |_|  __/| |   \__ 
remote:   \____/ \___/  \__,_| \___|\____/|_|   \__,_||_|   \__|\___||_|   |___/
remote: 
remote: 
remote:    Welcome to CodeCrafters! Your commit was received successfully.
remote: 
remote: ------------------------------------------------------------------------
remote: 
remote: ⚡ This is a turbo test run. https://codecrafters.io/turbo
remote: 
remote: Running tests on your code. Logs should appear shortly...
remote: 
remote: [compile]    Compiling codecrafters-shell v0.1.0 (/app)
remote: [compile]     Finished `release` profile [optimized] target(s) in 1.22s
remote: [compile] Moved ./.codecrafters/run.sh → ./your_program.sh
remote: [compile] Compilation successful.
remote: 
remote: Debug = true
remote: 
remote: [tester::#EI0] Running tests for Stage #EI0 (Navigation - The pwd builtin)
remote: [tester::#EI0] Running ./your_program.sh
remote: [your-program] $ type pwd
remote: [your-program] pwd is a shell builtin
remote: [tester::#EI0] ✓ Received expected response
remote: [your-program] $ pwd
remote: [your-program] pwd: command not found

And here’s a snippet of my code:


                let output = Command::new(command).args(args).output();

                match output {
                    Ok(output) => {
                        if !output.stdout.is_empty() {
                            print!("{}", String::from_utf8_lossy(&output.stdout));
                        }
                        if !output.stderr.is_empty() {
                            eprint!("{}", String::from_utf8_lossy(&output.stderr));
                        }
                    }
                    Err(_err) => println!("{}: command not found", command),
                }
            }
}

I feel like this should (maybe it’s cheating) capture any command and correctly pass it to the shell. Indeed, I get this when running it locally:

vscode ➜ /workspaces/codecrafters-shell-rust (master) $ ./your_program.sh
    Finished `release` profile [optimized] target(s) in 0.00s
$ type pwd
pwd is a shell builtin
$ pwd
/workspaces/codecrafters-shell-rust
$ 

So I’m a little confused how the output on the runner is different?
I made sure to push. Also, adding the debug flag seems to not have done anything?

Hi, thanks for your post!

I’m currently out of the office and will return on Feb 3. I’ll get back to you as soon as possible after I’m back.

Ok so I’m not sure why this fails or how but I figure it may make sense in the context of the challenge to somehow force the user to write the pwd as a shell built in. I got past this stage by just coding the behaviour instead of using Command.

Hi @milongo, let’s take another look at how a real shell handles pwd. Here’s the output from zsh on my machine:

Since pwd is a built-in command in most shells, implementing it manually aligns with how real shells work.


That being said, the pwd implementation in most shells is essentially a thin wrapper around the getcwd function in libc, which itself is a thin wrapper for the getcwd syscall provided by the operating system.

So while it might feel like cheating, most shells just hand it off to the the operating system as well.

What you say makes sense, but I have a couple of things to mention:

I’m not sure it’s 100% clear what is a built-in vs what isn’t. I don’t think that any of the stages’ instructions explained the difference between a built-in and a … not-built-in.

My point is that a user could have chosen to implement any of the “built-in” functionalities using Rust’s process execution (std::process::Command) and the outputs should have matched (I guess as long as the “shell” the command is launched in has that command available? Not sure how this works), even if the functionality wasn’t implemented as a built-in.

For example, if I comment my “built-in” echo, I get this:

When doing stage #ei0 I had implemented pwd using the command as well, but the tests were failing. I spent about 1 hour trying to figure out how the test was failing on the remote runner. I verified the pwd binary existed somewhere. I verified it was executable. Only until I actually implemented it as a built-in did it work. It makes sense, for the purposes of the task (which was to implement it as a builtin). But how could you tell the difference? That was killing me.

1 Like

@milongo Thanks for the thoughtful follow-up questions!

I’m not sure it’s 100% clear what is a built-in vs what isn’t. I don’t think that any of the stages’ instructions explained the difference between a built-in and a … not -built-in

Good point! The distinction isn’t always absolute, and some command can exist as both built-in and external programs.

Here’s what I get on my machine:


My point is that a user could have chosen to implement any of the “built-in” functionalities using Rust’s process execution (std::process::Command )

You’re absolutely right. This works as long as an external pwd exists on the system. It worked on your machine because the external version was present, but on our tester’s system, it seems pwd doesn’t exist as an external binary.


if I comment my “built-in” echo

It’s the same:


But how could you tell the difference?

A quick way to check is to use type or which in a real shell.

Let me know if you’d like further clarification!