JuliaLang/julia — pull request #1271 by carlobaldassi (2012-09-09 23:38:49+00:00)
Title: RFC: process redirections

This addresses #307 (and does a little more). There are 2 commits:

1) in the first one, I added file redirections. This allows things as:

```Julia
run(`ls` > "out.txt") # write to stdout
run(`ls` >> "out.txt") # append to stdout
run(`ls nonexistent.txt` .> "err.txt") # write to stderr
run(`ls nonexistent.txt` .>> "err.txt") # append to stderr
run("in.txt" > `grep xyz`) # read from stdin
```

Notice that I had to use `.>` for stderr, since `2>` is obviously unavailable. I also had to add `.>>` to the parser. This is as close I could get to the familiar shell syntax without introducing too many new operators, but if anyone comes up with a nicer alternative it would be great.

All forms have a mirror counterpart, e.g.

```Julia
run(`grep xyz` < "in.txt")
```

and can be used together, since the result of `(>)(::Cmd,::String)` is a Cmd, although they require brackets:

```Julia
run((`ls a b` > "out.txt") .> "err.txt")
```

which of course is a side-effect of using comparison operators and inheriting their precedence rules (one more reason to think of some alternative notation, if possible).

Everything works the same when using IOStreams instead of Strings:

```Julia
open("out.txt", "w") do f
run(`ls` > f)
end
```

but of course in that case there are no append operators, since the mode is inherited from the stream.

Apart from notation issues, I think the internals are sound, as I basically extended what's already done for pipes.

2) The second commit introduces here-strings and 2-in-1 redirections:

```Julia
run("one\ntwo\nthree" >>> `grep t`) # prints two and three
run(`ls a b` &> "both.txt") # redirects both stdout and stderr
run(`ls a b` &>> "both.txt") # same as above, append mode
```

There are also the mirror versions `<<<`, `&<` and `&<<`

So, even more extra operators...