I’m stuck on Stage #BR6.
Specifically this test:
remote: [tester::#BR6] [setup] echo -e “1. blueberry grape\n2. banana pear\n3. strawberry pineapple” > “/tmp/owl/file-68”
remote: [your-program] $ tail -f /tmp/owl/file-68 | head -n 5
remote: [tester::#BR6] Didn’t find expected line.
remote: [tester::#BR6] Expected: “1. blueberry grape”
remote: [tester::#BR6] Received: “” (no line received)
I implemented pipes between generic (non-embedded) commands, and it works as expected, except the case when STDOUT is not closed, like the case with tail -f.
The problem description talks about this example and explains that head -n 5 should print the partial output from tail even when less than 5 lines are available. My code only prints the output after all 5 lines are present - I assume that’s why the test fails with Received: "" (no line received).
The strange thing is I cannot make this scenario behave as explained even in my OS terminal. I’m on 25.10 Kubuntu. I tried both zsh and bash - both behaves the same way as my own code: only printing when all 5 lines are available. I tried Except’s unbuffer and stdbuf -o0 / -oL - nothing makes head print the initial 3 lines.
I also tried force flushing both stdout from head and the writer pipe from tail- no difference.
Readings suggest unbuffer and stdbuf should be able to influence the buffering from page/eof triggered to line/immediate - but I don’t see that at all.
My questions are:
- Am I interpreting the problem correctly? Should
head -n 5start printing before all 5 lines are there? - If so - how can I make this work in a generic Linux shell?
My code is at: https://git.codecrafters.io/8e7d70115cf7a285 (main.rs : line 443)
The idea is very basic, piping child processes - showing it in a simplified way:
let (reader, writer) = std::io::pipe().unwrap();
let mut child1 = std::process::Command::new("tail")
.arg("-f")
.arg("/tmp/foo")
.stdout(writer)
.spawn()
.unwrap();
let mut child2 = std::process::Command::new("head")
.arg("-n")
.arg("5")
.stdin(reader)
.spawn()
.unwrap();
child1.wait().unwrap();
child2.wait().unwrap();