[REPL Shell] Append to stderr

I’m stuck on Stage #UN3.

I’ve tried … (mention what you’ve tried so far).

Here are my logs:

[compile] Moved ./.codecrafters/run.sh → ./your_program.sh
[compile] Compilation successful.
[tester::#UN3] Running tests for Stage #UN3 (Redirection - Append stderr)
[tester::#UN3] [setup] export PATH=/tmp/strawberry/raspberry/raspberry:$PATH
[tester::#UN3] Running ./your_program.sh
[your-program] $ ls -1 nonexistent >> /tmp/baz/foo.md
[your-program] ls: nonexistent: No such file or directory
[tester::#UN3] ✓ Received error message
[tester::#UN3] ✓ File: /tmp/baz/foo.md is empty
[your-program] $ ls -1 nonexistent 2>> /tmp/baz/qux.md
[your-program] $ cat /tmp/baz/qux.md
[your-program] ls: nonexistent: No such file or directory
[tester::#UN3] ✓ Received redirected file content
[your-program] $ echo "James says Error" 2>> /tmp/baz/quz.md
[your-program] James says Error
[tester::#UN3] ✓ Received redirected file content
[your-program] $ cat nonexistent 2>> /tmp/baz/quz.md
[your-program] $ ls -1 nonexistent 2>> /tmp/baz/quz.md
[your-program] $ cat /tmp/baz/quz.md
[your-program] ls: nonexistent: No such file or directory
[tester::#UN3] Output does not match expected value.
[tester::#UN3] Expected: "cat: nonexistent: No such file or directory"
[tester::#UN3] Received: "ls: nonexistent: No such file or directory"
[your-program] $ 
[tester::#UN3] Assertion failed.
[tester::#UN3] Test failed (try setting 'debug: true' in your codecrafters.yml to see more details)

And here’s a snippet of my code:

import sys
import shutil
import os
import shlex
import contextlib


def main():
    builtins = {"type", "exit", "echo", "pwd", "cd"}

    while True:
        sys.stdout.write("$ ")
        command = sys.stdin.readline().strip().replace('1>', '>')

        cmd = shlex.split(command, posix=True)
        stdout = sys.stdout if ">" not in command else open(cmd[-1], f'{"a" if ">>" in cmd else "w"}+')

        match cmd:
            case ["exit", arg]: sys.exit(int(arg))
            case ["exit"]: sys.exit(0)
            case ["echo", *args]: (stdout if '2>' not in args and '2>>' not in args else sys.stdout).write(f"{' '.join(args if stdout == sys.stdout else args[:-2])}\n")
            case ["type", arg] if arg in builtins: stdout.write(f"{arg} is a shell builtin\n")
            case ["type", arg] if path := shutil.which(arg): stdout.write(f"{arg} is {path}\n")
            case ["type", arg] if arg not in builtins: stdout.write(f"{arg}: not found\n")

            case ["pwd"]: sys.stdout.write(f"{os.getcwd()}\n")
            case ["cd", dir_path] if (path_exists := os.path.exists(expanded := os.path.expanduser(dir_path))): os.chdir(expanded)
            case ["cd", dir_path] if not path_exists: stdout.write(f"cd: {os.path.expanduser(dir_path)}: No such file or directory\n")

            case [fn, *args] if shutil.which(fn): os.system(command)
            case [fn, *args] if not shutil.which(fn): stdout.write(f"{fn}: command not found\n")
        
        if ">" in command:
            stdout.close()


if __name__ == "__main__":
    main()

The reason I’m confused is because this code should work. If anyone could help that’d be great!

Hi @encryptedoreo, could you upload your code to GitHub and share the link? It will be much easier to debug if I can run it directly.

Hi @andy1li, I have published my code to GitHub. Could you please help me debug my code?

Sure, mind sharing the link?

It seems os.system is not handling 2>> correctly and is treating it as 2>, which overwrites the file instead of appending to it:

To avoid this issue, consider using subprocess.run with shell=True.

I still seem to have the same problem after changing it to subprocess.run(command, shell=True, text=True). Now it just lists the directories.

@encryptedoreo Sorry for delayed response!

Looks like relying on the shell features in Python might not be enough anymore.

You may need to implement some of that behavior manually. Let me know if you’d like a hand with that!

Closing this thread due to inactivity. If you still need assistance, feel free to reopen or start a new discussion!

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.