interp: handle bash >|, >>|, &>|, &>>|, <> redirects#1333
Open
qiangli wants to merge 1 commit into
Open
Conversation
The parser already recognises these tokens (RdrClob, AppClob, RdrAllClob, AppAllClob, RdrInOut), but the runtime in interp/runner.go only threaded RdrIn/RdrOut/AppOut/RdrAll/AppAll through its three dispatch switches inside (*Runner).redir. The remaining operators fell to the default branch and exited with "unhandled redirect op", so any script using them failed even though plain `>`/`>>` worked. This shows up most often through templates that wrap user commands in a `>|` to force-overwrite a known temp file (for example, capturing $PWD across a persistent-shell invocation), where the embedded interpreter's exit then propagates back to the caller as a generic failure. Treat the four "Clob" variants as identical to their plain counterparts — they only differ from `>`/`>>`/`&>`/`&>>` in that they bypass the noclobber shell option (set -C), and this interpreter does not enforce noclobber on file redirects today. RdrInOut (<>) opens the target with O_RDWR|O_CREATE and binds it to the input fd; we plumb the result through stdinFile so reads work. Writes back through fd 0 are not propagated since stdin is exposed as io.Reader internally — sufficient for the read-side use that accounts for nearly all real <> usage. Adds four entries in the existing redirect table in interp/interp_test.go covering >| (new file, overwrite) and <> (read existing, create-if-missing).
6df2b90 to
7f62652
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
(*Runner).redirininterp/runner.goonly threadedRdrIn,RdrOut,AppOut,RdrAll, andAppAllthrough its three dispatch switches. The remaining file-redirect operators that the parser already recognises —RdrClob(>|),AppClob(>>|),RdrAllClob(&>|),AppAllClob(&>>|), andRdrInOut(<>) — fell to thedefault: unhandled redirect op: %vbranch and exited with an error, so any script using them failed even though plain>/>>worked.This shows up most often in templates that wrap a user command in a fixed
>|to force-overwrite a known temp file. With those failing, an embedded interpreter looks broken from the caller's perspective even when the user's command itself succeeded.Approach
*Clobvariants as identical to their plain counterparts. They only differ from>/>>/&>/&>>in that they bypass the noclobber shell option (set -C), and the interpreter does not enforce noclobber on file redirects today, so the runtime behaviour is the same.<>(RdrInOut), open the target withO_RDWR|O_CREATEand bind it throughstdinFileso reads work. Writes back through fd 0 are not propagated to the file because stdin is exposed asio.Readerinternally — sufficient for the read-side use that accounts for nearly all real<>usage.Test plan
interp/interp_test.gocovering>|(new file, overwrite-existing) and<>(read-existing, create-if-missing).go test -short ./interp/ ./syntax/passes.