Skip to content

backticks: implement piping and std{in,out,err} redirection#61540

Open
StefanKarpinski wants to merge 1 commit intomasterfrom
sk/backticks-redirects
Open

backticks: implement piping and std{in,out,err} redirection#61540
StefanKarpinski wants to merge 1 commit intomasterfrom
sk/backticks-redirects

Conversation

@StefanKarpinski
Copy link
Copy Markdown
Member

Adds shell-style pipe and redirection operators to backtick command literals. Part of #20401. Examples:

julia> run(`ls -1 | sort -r > /tmp/out.txt`)

julia> read(`cat < /tmp/out.txt | head -5`, String)

julia> run(`make 2> /tmp/errors.txt`)

julia> file = "/usr/share/dict/words"
"/usr/share/dict/words"

shell> tail $file | sort -r
Zyzzogeton
Zyzomys
zythum
Zythia
zythem
Zyryan
Zyrian
Zyrenian
zymurgy
zymotoxic

Supported operators

Syntax Meaning
cmd1 | cmd2 Pipe stdout of cmd1 to stdin of cmd2
cmd > file Redirect stdout to file
cmd >> file Append stdout to file
cmd < file Redirect file to stdin
cmd 2> file Redirect stderr to file
cmd 2>> file Append stderr to file
cmd 1> file Explicit stdout redirect (same as >)
cmd 0< file Explicit stdin redirect (same as <)

These lower to pipeline() calls at parse time. Simple commands without operators still return Cmd as before.

Display round-tripping

Pipeline and redirect objects display using backtick syntax when possible:

julia> `echo hello | sort > out.txt`
`echo hello | sort > out.txt`

julia> `make 2> errors.txt`
`make 2> errors.txt`

Commands with non-representable features (e.g. custom env, setuid) fall back to the existing pipeline(...) display format.

REPL shell mode

Shell mode now handles pipes and redirects. Before:

shell> echo hello | wc -c
hello | wc -c

After:

shell> echo hello | wc -c
6

In other words, previously shell mode would pass the | as a literal argument to the echo command; now it constructs a pipeline just as run(`echo hello | wc -c`) would.

Implementation notes

  • Operators inside quotes are treated as literal characters ('|', '>'), matching shell behavior
  • Fd prefixes require unquoted integers: '2'>file redirects stdout with argument "2", not stderr (POSIX-compliant)
  • Filenames in redirects support $ interpolation
  • Stderr redirects use a separate pipeline() call so stdout and stderr can have independent append modes

This PR was written with the assistance of generative AI.

@StefanKarpinski StefanKarpinski force-pushed the sk/backticks-redirects branch from 26f2b0e to 12a50f8 Compare April 9, 2026 03:23
@StefanKarpinski StefanKarpinski marked this pull request as draft April 9, 2026 13:29
@StefanKarpinski
Copy link
Copy Markdown
Member Author

Converted to draft since it should not be merged until #61397 is (or not).

@StefanKarpinski StefanKarpinski requested a review from vtjnash April 9, 2026 13:30
@StefanKarpinski
Copy link
Copy Markdown
Member Author

Triage likes being able to use the syntax, but is unsure about the change to printing of pipeline objects, but may come around. The conservative approach here may be to revert the printing change part, merge that, and then open the printing change as its own, separate PR that we can decide later on if we want or not.

@StefanKarpinski
Copy link
Copy Markdown
Member Author

The argument for printing as explicit pipeline calls (aside from not changing printing being more conservative inherently), was that Julia programmers are expected to know how to construct these things programmatically, so showing that to them seems reasonable. My counterpoint was that I still cannot remember how to construct moderately complex pipelines using Julia syntax, whereas I very much know how to do it with shell syntax.

@StefanKarpinski StefanKarpinski force-pushed the sk/backticks-redirects branch 3 times, most recently from b1546b3 to 1cae1de Compare April 10, 2026 21:46
@StefanKarpinski StefanKarpinski force-pushed the sk/backticks-redirects branch 2 times, most recently from 53bead2 to 33b8361 Compare April 11, 2026 16:00
Implement `|`, `<`, `>`, `>>`, `2>`, `2>>`, `1>`, and `0<` operators
in backtick command literals. These lower to `pipeline()` calls at
parse time, so `` `ls | sort > out.txt` `` works as expected.

Fd-prefixed redirects (`2>`, `1>`, `0<`) require an unquoted integer
before the operator — quoted integers like `'2'>file` are treated as
regular arguments, matching POSIX shell behavior.

The REPL shell mode is updated to handle pipeline/redirect commands,
which previously failed with a `MethodError` on `length(::OrCmds)`.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@StefanKarpinski StefanKarpinski force-pushed the sk/backticks-redirects branch from 33b8361 to ad10b28 Compare April 11, 2026 16:33
@StefanKarpinski StefanKarpinski marked this pull request as ready for review April 11, 2026 16:33
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.

1 participant