#VZ4 Failed to read file ("/tmp/bar/baz.md"): open /tmp/bar/baz.md: no such file or directory

I’m stuck on Stage #VZ4.

Is this asking me to handle the error where the redirected path is nonexistent? In this case what is the desired output?

Here are my logs:

[your-program] $ ls -1 nonexistent 2> /tmp/bar/bar.md
[your-program] $ cat /tmp/bar/bar.md
[your-program] ls: nonexistent: No such file or directory
[tester::#VZ4] ✓ Received redirected error message
[your-program] $ echo 'Emily file cannot be found' 2> /tmp/bar/baz.md
[tester::#VZ4] Failed to read file ("/tmp/bar/baz.md"): open /tmp/bar/baz.md: no such file or directory
[your-program] Emily file cannot be found
[your-program] $ 
[tester::#VZ4] Assertion failed.
[tester::#VZ4] Test failed

And here’s all of my code:

import sys
import os
import shlex

# TODO: Refactor to use match-case instead of elifs
# Can even make functions as well

def write_output(output, filepath_location, output_type, redirect_type):
    if filepath_location and (output_type == redirect_type):
        with open(filepath_location, 'w') as f:
            f.write(output)
    else:
        sys.stdout.write(output)
            

def main():

    
    builtIns = ["exit", "echo", "type", "pwd", "cd"]

    while True:

        PATH = os.environ.get("PATH", "")
        HOME = os.environ.get("HOME")
        paths = PATH.split(":")

        # Uncomment this block to pass the first stage
        sys.stdout.write("$ ")

        # Wait for user input
        user_input = input()
        command = user_input.strip()


        words = user_input.split(" ")
        cmd_tail = " ".join(words[1:])
        # notice the difference between words and args, that will probably be the cause of some errors
        # note args[0] and words[0] will be equal unless the input begins with a quote (which will just be an unknown command)
        args = shlex.split(command, posix=True)
        cmd = args[0]
        
        # file redirecting
        # vulnerability if someone just writes a "> " anywhere
        filepath_location = None
        redirect_type = None
        if "> " in user_input:
            for i, arg in enumerate(args):
                if ">" in arg:

                    # classify the redirect type
                    if (" 1> " in user_input) or (" > " in user_input):
                        redirect_type = "out"
                    elif (" 2> " in user_input):
                        redirect_type = "err"

                    filepath_location = args[i+1]
                    # remove the redirect from the tail and args
                    args = args[:i]
                    cmd_tail = " ".join(words[1:i])
                    break
        


        try:

            


            if cmd == "exit":
                sys.exit(int(cmd_tail))

            elif cmd == "echo":
                output = f"{" ".join(args[1:])}\n"
                write_output(output, filepath_location, "out", redirect_type)

            elif cmd == "type":
                current_path = None
                for path in paths:
                    if os.path.isfile(f"{path}/{cmd_tail}"):
                        current_path = f"{path}/{cmd_tail}"
                        break
                if cmd_tail in builtIns:
                    output = f"{cmd_tail} is a shell builtin\n"
                    write_output(output, filepath_location, "out", redirect_type)
                elif current_path:
                    output = f"{cmd_tail} is {current_path}\n"
                    write_output(output, filepath_location, "out", redirect_type)
                else:
                     output = f"{cmd_tail}: not found\n"
                     write_output(output, filepath_location, "out", redirect_type)
            elif cmd == "pwd":
                output = f"{os.getcwd()}\n"
                write_output(output, filepath_location, "out", redirect_type)
            elif cmd == "cd":
                try:
                    os.chdir(cmd_tail)
                except OSError as err:
                    if cmd_tail == "~":
                        os.chdir(HOME)
                    else:
                        output = f"cd: {cmd_tail}: No such file or directory\n"
                        write_output(output, filepath_location, "err", redirect_type)

            else:

                # Execute executable or skip
                current_path = None
                for path in paths:
                    if os.path.isfile(f"{path}/{cmd}"):
                        os.system(user_input)
                        break
                else:
                    output = f"{user_input}: command not found\n"
                    write_output(output, filepath_location, "err", redirect_type)

        # The tester likes a certain error output
        except OSError as err:
            write_output(f"OS error: {err}\n", filepath_location, "err", redirect_type)
        except ValueError:
            write_output("Could not convert data to an integer\n", filepath_location, "err", redirect_type)
        except Exception as err:
            write_output(f"Unexpected {err=}, {type(err)=}\n", filepath_location, "err", redirect_type)
            raise


if __name__ == "__main__":
    main()

I added a try except to the write_output function:

try:
     with open(filepath_location, 'w') as f:
                f.write(output)
except FileNotFoundError:
                write_output(f"Failed to read file ({filepath_location}): file does not exist", "out", redirect_type)

but I don’t think the error is occurring at file opening as I get the standard system error message instead of my custom one:

[your-program] $ echo 'David file cannot be found' 2> /tmp/baz/foo.md
[tester::#VZ4] Failed to read file ("/tmp/baz/foo.md"): open /tmp/baz/foo.md: no such file or directory
[your-program] David file cannot be found
[your-program] $ 
[tester::#VZ4] Assertion failed.
[tester::#VZ4] Test failed

Ok, the error is when the tester itself goes to read the file. So either, the file doesn’t exist, or I am moving or renaming the file inadvertently. Ok, I understand the issue now. output_type != redirect type in this case. I have misunderstood the task.

1 Like

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