I’m stuck on Stage #Build your own shell #VZ4.
It keeps saying the file doesn’t exist while I’m not even trying to open that file, since the condition ‘has_error’ is False
Here are my logs:
remote: [your-program] $ echo 'David file cannot be found' 2> /tmp/quz/baz.md
remote: [tester::#VZ4] Failed to read file ("/tmp/quz/baz.md"): open /tmp/quz/baz.md: no such file or directory
remote: [your-program] David file cannot be found
And here’s a snippet of my code:
def execute_command(user_command):
has_error = False
match shlex.split(user_command):
case ["exit", *_]:
exit(0)
case ["echo", *message]:
return f'{" ".join(message)}\n', has_error
case ["cat", *files]:
return cat(files)
case ["pwd", *_]:
return f"{os.getcwd()}\n", has_error
case ["cd", *path]:
new_path = os.path.expanduser(" ".join(path))
try:
os.chdir(new_path)
except FileNotFoundError:
has_error = True
return f"cd: {new_path}: No such file or directory\n", has_error
case ["type", *command]:
cmd = " ".join(command)
if cmd in valid_commands:
return f"{cmd} is a shell builtin\n", has_error
else:
cmd_path = find_excutable_path(cmd)
if cmd_path:
return f"{cmd} is {cmd_path}\n", has_error
else:
has_error = True
return f"{cmd}: not found\n", has_error
case ["ls", *args]:
try:
output = subprocess.run(
["ls", *args],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
check=True,
).stdout.decode()
return output, has_error
except subprocess.CalledProcessError:
has_error = True
return f"ls: {args[0]}: No such file or directory\n", has_error
case [cmd, *args]:
is_cmd = False
paths = os.environ["PATH"].split(":")
for path in paths:
if os.path.exists(f"{path}/{cmd}"):
output = subprocess.run(
[f"{path}/{cmd}", *args], stdout=subprocess.PIPE
).stdout.decode()
is_cmd = True
if is_cmd:
return output, has_error
else:
has_error = True
return f"{user_command}: command not found\n", has_error
def main():
"""shell implementation"""
while True:
sys.stdout.write("$ ")
user_command = input()
res_pattern = r"(.*?)\s*(?:1)?\s*>\s*(.*)"
err_pattern = r"(.*?)\s2>\s(.*)"
res_match = re.match(res_pattern, user_command)
err_match = re.match(err_pattern, user_command)
if not res_match and not err_match:
output, _ = execute_command(user_command)
if output:
sys.stdout.write(output)
elif err_match:
input_cmd, to_file = err_match.groups()
assert to_file
left_output, has_error = execute_command(input_cmd)
if has_error and to_file:
with open(to_file, "w") as f:
f.write(left_output)
else:
sys.stderr.write(left_output)
else:
input_cmd, to_file = res_match.groups()
left_output = execute_command(input_cmd)
with open(to_file, "w") as f:
f.write(left_output)