[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.