Skip to content

Commit 84f0f4a

Browse files
authored
fix(interpreter): exec < file redirects stdin for subsequent commands (#1030)
## Summary - When `exec < file` has no explicit fd, set `pipeline_stdin` to the file content so subsequent `read`/`cat` commands consume it - Hoisted file-reading logic out of the fd check to share between named-fd and default-stdin paths ## Test plan - [x] `exec_stdin_redirect` spec test — `exec < file` + `read` reads from file - [x] Smoke test via CLI confirms end-to-end behavior - [x] All existing exec and bash spec tests still pass Closes #960
1 parent d3521e6 commit 84f0f4a

File tree

2 files changed

+17
-4
lines changed

2 files changed

+17
-4
lines changed

crates/bashkit/src/interpreter/mod.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3643,14 +3643,17 @@ impl Interpreter {
36433643
for redirect in redirects {
36443644
match redirect.kind {
36453645
RedirectKind::Input => {
3646+
let target_path = self.expand_word(&redirect.target).await?;
3647+
let path = self.resolve_path(&target_path);
3648+
let content = self.fs.read_file(&path).await?;
3649+
let text = bytes_to_latin1_string(&content);
36463650
if let Some(fd) = redirect.fd {
3647-
let target_path = self.expand_word(&redirect.target).await?;
3648-
let path = self.resolve_path(&target_path);
3649-
let content = self.fs.read_file(&path).await?;
3650-
let text = bytes_to_latin1_string(&content);
36513651
let lines: Vec<String> =
36523652
text.lines().rev().map(|l| l.to_string()).collect();
36533653
self.coproc_buffers.insert(fd, lines);
3654+
} else {
3655+
// exec < file: redirect stdin for subsequent commands
3656+
self.pipeline_stdin = Some(text);
36543657
}
36553658
}
36563659
RedirectKind::DupInput => {

crates/bashkit/tests/spec_cases/bash/exec-command.test.sh

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,3 +81,13 @@ echo "after exec redirect"
8181
### expect
8282
after exec redirect
8383
### end
84+
85+
### exec_stdin_redirect
86+
# exec < file should redirect stdin for subsequent commands
87+
echo "from file" > /tmp/exec_stdin_test.txt
88+
exec < /tmp/exec_stdin_test.txt
89+
read -r line
90+
echo "got: $line"
91+
### expect
92+
got: from file
93+
### end

0 commit comments

Comments
 (0)