Build your own shell: Dual-command pipeline error

I’m stuck on Dual-command pipeline stage. Here are my logs:

[tester::#BR6] Running tests for Stage #BR6 (Pipelines - Dual-command pipeline)
[tester::#BR6] [setup] export PATH=/tmp/mango/orange/mango:$PATH
[tester::#BR6] Running ./your_program.sh
[tester::#BR6] [setup] echo -e "banana blueberry\norange pear\napple raspberry\nmango pineapple\ngrape strawberry" > "/tmp/fox/file-46"
[your-program] $ cat /tmp/fox/file-46 | wc
[your-program]        5      10      78
[tester::#BR6] ✓ Received expected response
[tester::#BR6] [setup] echo -e "1. blueberry banana\n2. apple raspberry\n3. mango grape" > "/tmp/owl/file-50"
[your-program] $ 
[tester::#BR6] ^ Line does not match expected value.
[tester::#BR6] Expected: "$ tail -f /tmp/owl/file-50 | head -n 5"
[tester::#BR6] Received: "$ "
[tester::#BR6] Assertion failed.
[tester::#BR6] Test failed

As far as I understand, what is happening is, that after executing “cat /tmp/fox/file-46 | wc”, forked subprocess “wc” outputs expected output in stdout, tester accepts it and inputs the next command, but since my shell proces waits for children to terminate, “$ “ appears only after tester inputed next commands. Can my assumptions be right?

PS: I disabled built-ins for this stage, but I doubt this matters now, since the test using only external programs

Not sure if regular users are welcomed here. But I solved this challenge recently, so my word might be valuable.

  1. You’ll deal with built-ins a bit later, wait for it (for me, it was painful)
  2. Can you reproduce this issue? Does the cat filename | wc works fine on your machine? Does it work like a real shell?
  3. I am not sure about the language you write, but the main thing in my Python was – to close the input. It took me a lot of refactorings to get what it mean, so hopefully you’ll get there too.
1 Like

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

GitHub - Stardustpixels/codecrafters-shell-cpp Here’s it

Hi, thanks for your reply! @natalka1122

  1. Yeah, I don’t really wait for it eagerly haha
  2. It does run ok on my machine, but I think the timing might be off if we test automatically.
  3. Can you elaborate on that one? I work in c++ using fork()/dup()/close(), but it still seems relevant. Do you mean you close input of shell process when running subprocesses?

@Stardustpixels
Say you have this pipeline:
cmd1 | cmd2
For cmd1 there is no input, no need to close anything.
When cmd1 ends the job (say it is cat of a file then there is an end, for tail -f there is no possilbe end), cmd2 should be informed that no new data is comming, aka close the input. Otherwise it is stuck forever waiting.

Sorry, donno what is happening under the hood, can only show my python code: codecrafters-shell-python/app/async_command_processor.py at cbe55f98c7b7d75a27eed31b72d85e938cafa7de · natalka1122/codecrafters-shell-python · GitHub

I ran into the same issue recently, and since I struggled with it myself, I (somewhat egoistically) assume everyone else must be hitting it too :grinning_face:

PS: Adding builtins is the best part of this challenge, especially with Multi-command pipelines

@Stardustpixels I tried running your code against the previous stages, but it’s actually no longer passing a previous stage #CZ2 (Handle invalid commands).

Suggestions:

  1. Use our CLI to test against previous stages by running:
codecrafters test --previous
  1. Focus on fixing the early stages first, as later stages depend on them.