Shell challenge: previous test randomly crashing

I’m stuck on Stage #GY5

My program passes all the completion tests, but fails at the append std out/err test by echoing the command, the behaviour is not consistent:

Passed test:

remote: [tester::#UN3] Running tests for Stage #UN3 (Redirection - Append stderr)
remote: [tester::#UN3] [setup] export PATH=/tmp/strawberry/mango/strawberry:$PATH
remote: [tester::#UN3] Running ./your_program.sh
remote: [your-program] $ ls -1 nonexistent >> /tmp/bar/bar.md
remote: [your-program] ls: nonexistent: No such file or directory
remote: [tester::#UN3] ✓ Received error message
remote: [tester::#UN3] ✓ File: /tmp/bar/bar.md is empty
remote: [your-program] $ ls -1 nonexistent 2>> /tmp/bar/foo.md
remote: [your-program] $ cat /tmp/bar/foo.md
remote: [your-program] ls: nonexistent: No such file or directory
remote: [tester::#UN3] ✓ Received redirected file content
remote: [your-program] $ echo "Emily says Error" 2>> /tmp/bar/quz.md
remote: [your-program] Emily says Error
remote: [tester::#UN3] ✓ Received redirected file content
remote: [your-program] $ cat nonexistent 2>> /tmp/bar/quz.md
remote: [your-program] $ ls -1 nonexistent 2>> /tmp/bar/quz.md
remote: [your-program] $ cat /tmp/bar/quz.md
remote: [your-program] cat: nonexistent: No such file or directory
remote: [your-program] ls: nonexistent: No such file or directory
remote: [tester::#UN3] ✓ Received redirected file content
remote: [your-program] $
remote: [tester::#UN3] Test passed.

Failed test:

remote: [your-program] $ ls -1 nonexistent >> /tmp/baz/bar.md
remote: [your-program] ls: nonexistent: No such file or directory
remote: [tester::#UN3] ✓ Received error message
remote: [tester::#UN3] ✓ File: /tmp/baz/bar.md is empty
remote: [your-program] $ ls -1 nonexistent 2>> /tmp/baz/foo.md
remote: [your-program] $ cat /tmp/baz/foo.md
remote: [your-program] ls: nonexistent: No such file or directory
remote: [tester::#UN3] ✓ Received redirected file content
remote: [your-program] $ echo "Emily says Error" 2>> /tmp/baz/qux.md
remote: [your-program] Emily says Error
remote: [tester::#UN3] ✓ Received redirected file content
remote: [your-program] $ cat nonexistent 2>> /tmp/baz/qux.md
remote: [your-program] cat nonexistent 2>> /tmp/baz/qux.md
remote: [tester::#UN3] Expected prompt ("$ ") but received "cat nonexistent 2>> /tmp/baz/qux.md"
remote: [your-program] $
remote: [tester::#UN3] Assertion failed.

cat and ls are executed by subprocess.run() function:

case default:
                if identifier := shutil.which(identifier if identifier else ''):
                    subprocess.run(command_foo, shell = True)
                else:
                    print(f'{command}: command not found')

where command_foo variable is a string copy of inputted command

Hey @MU14531453, 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, sharing link:

@MU14531453 Looks like the current implementation is not actually handling redirections (expect for echo):

Using subprocess.run(command_foo, shell = True) kind of defeats the purpose of building your own shell. :sweat_smile:

Well yes, however - stage instructions advise to not implement cat and ls:

“The cat command is an executable available on most systems, so there’s no need to implement it yourself.”, since I already pass the cat/ls call to subprocess.run() which handles redirection by itself, stopping this redirection jut to use my own function seems very excessive

Totally understandable! There’s a subtle distinction here:

  • Commands like cat and ls aren’t built into the shell. They’re standalone executables.

  • Redirection, on the other hand, is a shell feature. It can either be handled by your own shell (which is the goal here) or delegated to another shell using shell=True (In the latter case, your shell isn’t actually handling redirection per se).

Hi, I get the difference now, however it doesn’t affect my original problem - since I had passed the redirection tests before using the easy way, the bug must origin somewhere in the line autocompletion code, and I have no idea how to hunt for it as of now - there seems to be no clear difference between passed/failed test from my original post

@MU14531453 There might be multiple issues at play. Here are the first two that I noticed:

  1. It’s unclear why multiple commands are being joined into a single string before being appended to completer.commands.

Instead, you can append multiple commands using extend:

dynamic_commands = os.listdir(dynamic_path)
completer.commands.extend(dynamic_commands)

  1. completer.commands may end up with duplicate entries, which can be removed by:
completer.commands = list(set(completer.commands))

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