Skip to content

Commit c698056

Browse files
committed
fix(spec): drive fish mock with head -n 1 instead of read+/dev/stdin
fish 3.x's `read` builtin closes stdin after the first line when run from a `-c` script with a piped stdin (fish-shell/fish-shell#5714). The previous `read -l LINE < /dev/stdin` worked around it on Linux but on macOS BSD `/dev/stdin` opens via /dev/fd/0, which EOFs on the second iteration and silently killed the loop — every fish case after the first failed with a broken pipe (and an empty exception message). Replace the `read` loop with `head -n 1` per iteration. The simulator is strictly synchronous (one line in, one response out), so `head`'s read-ahead never eats data the next iteration would need.
1 parent 5b51c6e commit c698056

1 file changed

Lines changed: 10 additions & 1 deletion

File tree

src/tabular/shell/fish.ecr

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,16 @@
11
<% completers.each do |comp| -%>
22
<%= comp %> completion <%= bin %> | source
33
<% end %>
4-
while read -l LINE < /dev/stdin
4+
# fish 3.x's `read` builtin closes stdin after the first line when invoked
5+
# from a `-c` script with a piped stdin. The historical workaround was
6+
# `read -l LINE < /dev/stdin`, but on macOS BSD that opens a fresh fd via
7+
# /dev/fd/0 which EOFs on the second iteration and silently kills the loop.
8+
# `head -n 1` sidesteps the buffering quirk on both platforms; relying on
9+
# the simulator being synchronous (one line in / one response out) keeps
10+
# its read-ahead from eating subsequent lines.
11+
while true
12+
set -l LINE (head -n 1)
13+
test -z "$LINE"; and break
514
complete -C "<%= prog %> $LINE"
615
printf '\0'
716
end

0 commit comments

Comments
 (0)