Skip to content

parser, executor: implement named file-descriptor redirections ({var}>file) - #276

Merged
brianjfox merged 1 commit into
mainfrom
feat/varfd-redirections
Jul 24, 2026
Merged

parser, executor: implement named file-descriptor redirections ({var}>file)#276
brianjfox merged 1 commit into
mainfrom
feat/varfd-redirections

Conversation

@brianjfox

Copy link
Copy Markdown
Owner

Fixes #275.

Root cause

The {varname} file-descriptor redirection form was unsupported — {fd} was taken as an ordinary word (exec {fd}>fileexec: {fd}: not found).

Implementation

  • AST: Redirect.fd_var.
  • Parser: recognize an unquoted {name} glued to a redirection operator (in both parse_simple and parse_redirect_list), so a {name} before a redirection is the fd-variable specifier rather than a command word.
  • Executor: apply_redirect allocates a fresh high, close-on-exec descriptor, opens the redirection on it, and stores its number in the variable. It is recorded as an originally-closed fd, so a normal command closes it afterwards while exec keeps it open (the variable keeps the number). {var}>&-/{var}<&- close the descriptor the variable currently names.
  • to_string: declare -f reconstruction emits the {name} prefix.

Supports <, >, >>, <>, >&N, <&N, >&-, <&-, and <<EOF, on simple and compound commands, with exec (permanent) or a command (temporary).

Verification

  • exec {fd}>file; echo hi >&$fd; exec {fd}>&-; cat filehi; {fd}<file reads; {fd}<>file, {fd}>&1, heredoc {v}<<EOF, group { ...; } {fd}<file — all match bash 5.3; the variable holds an integer ≥ 10.
  • Non-glued {fd} >file, quoted "{fd}", and brace expansion {a,b}>file are unaffected.
  • vredir scoreboard: 125 → 33.
  • Execution differential 234/234; real-script parser corpus 429/429; negative corpus 68/68 (0 leniency).

Known limitations (the residual vredir diffs)

  • bash's exact cannot assign fd to variable / ambiguous redirect / Bad file descriptor error text for unassignable (nameref/readonly) or invalid fd-vars is not reproduced; because those cases now run instead of failing to parse, nameref ticks up slightly (248 → 258) — a byte-diff artifact, not broken behavior.
  • Array-element fd targets ({fd[0]}<&0) and bash's specific high-descriptor numbering are not implemented.

The {varname} redirection form was unsupported -- {fd} was taken as an
ordinary word, so exec {fd}>file failed with "exec: {fd}: not found".

Add Redirect.fd_var; recognize an unquoted {name} glued to a redirection
operator in both parse_simple and parse_redirect_list; and in apply_redirect
allocate a fresh high, close-on-exec descriptor, open the redirection on it,
and store its number in the variable.  The descriptor is recorded as an
originally-closed fd so a normal command closes it afterwards while exec keeps
it (the variable retains the number).  {var}>&- / {var}<&- close the descriptor
the variable currently names; here-documents and here-strings are supported
too.  declare -f reconstruction prints the {name} prefix.

Handles <, >, >>, <>, >&N, <&N, >&-, <&-, and <<EOF forms, on simple and
compound commands, with exec (permanent) or a command (temporary).  Reduces the
vredir test-suite file 125 -> 33; the remainder is bash's exact
cannot-assign/ambiguous-redirect error text, array-element fd targets
({fd[0]}), and the specific high-descriptor numbers, all separate.
@brianjfox
brianjfox merged commit 06337dd into main Jul 24, 2026
1 check passed
@brianjfox
brianjfox deleted the feat/varfd-redirections branch July 24, 2026 10:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Named file-descriptor redirections ({var}>file) are unsupported

1 participant