diff --git a/crates/bashkit/src/interpreter/mod.rs b/crates/bashkit/src/interpreter/mod.rs index 08fe21e9..81df30dc 100644 --- a/crates/bashkit/src/interpreter/mod.rs +++ b/crates/bashkit/src/interpreter/mod.rs @@ -3643,14 +3643,17 @@ impl Interpreter { for redirect in redirects { match redirect.kind { RedirectKind::Input => { + let target_path = self.expand_word(&redirect.target).await?; + let path = self.resolve_path(&target_path); + let content = self.fs.read_file(&path).await?; + let text = bytes_to_latin1_string(&content); if let Some(fd) = redirect.fd { - let target_path = self.expand_word(&redirect.target).await?; - let path = self.resolve_path(&target_path); - let content = self.fs.read_file(&path).await?; - let text = bytes_to_latin1_string(&content); let lines: Vec = text.lines().rev().map(|l| l.to_string()).collect(); self.coproc_buffers.insert(fd, lines); + } else { + // exec < file: redirect stdin for subsequent commands + self.pipeline_stdin = Some(text); } } RedirectKind::DupInput => { diff --git a/crates/bashkit/tests/spec_cases/bash/exec-command.test.sh b/crates/bashkit/tests/spec_cases/bash/exec-command.test.sh index bb6b65a8..39d2f936 100644 --- a/crates/bashkit/tests/spec_cases/bash/exec-command.test.sh +++ b/crates/bashkit/tests/spec_cases/bash/exec-command.test.sh @@ -81,3 +81,13 @@ echo "after exec redirect" ### expect after exec redirect ### end + +### exec_stdin_redirect +# exec < file should redirect stdin for subsequent commands +echo "from file" > /tmp/exec_stdin_test.txt +exec < /tmp/exec_stdin_test.txt +read -r line +echo "got: $line" +### expect +got: from file +### end