Open jpco opened 1 year ago
cat < <{echo *}
and echo * > >{cat}
should both be (mostly) behaviorally equivalent to %pipe {echo *} 1 0 {cat}
, if this worked, and i can't see a good reason to implement this when the net outcome is the same as with a regular pipe.
Another non-sh shell, fish, currently does not have a %writeto
equivalent, but it does have %readfrom
in the form of cmd (subcmd | psub)
.
The fish equivalent of cmd < <{subcmd}
, i.e. cmd < (subcmd | psub)
, just happens to work because of how psub
works; it isn't intended to be used in that way.
The difference between cat < <{echo *}
, echo * > >{cat}
, and echo * | cat
come down to which command runs in the local process (for this example, pretend cat
is a builtin).
As es works today, echo * | cat
runs both commands in subshells (this is what #55 would change if merged). The %readfrom
and %writeto
based examples, however, run their respective "outer" command in the local shell, which allows more side effects.
You can see this in action by manually "parsing" the syntax down to hook functions:
; a = b
; {a = c; echo foo bar} | rev
rab oof
; echo $a
b
; # {a = c; echo foo bar} > >{rev}
; %writeto _devfd1 {rev} {%create 1 <={%one $_devfd1} {a = c; echo foo bar}}
rab oof
; echo $a
c
I find the whole "use process substitution to work around pipes being executed in a subprocess" thing in bash to be obnoxious, but at least there's some syntax at all for it.
I can see your reasoning, but %writeto var {cmd > $var}
works fine already:
; # Simple example: equivalent of non-working
# {a = c; echo foo bar} > >{rev}
; a = b
; %writeto _devfdz {rev} {{a = c; echo foo bar} > $_devfdz}
rab oof
; echo $a
c
And %readfrom var input {cmd < $var}
works as well, if you need Bash's lastpipe
behavior as proposed in #55:
; # Adapted from PR #55: equivalent of non-working
# {for-each @ l{ accum = $accum $l }} < <{cat input}
; fn for-each lambda {
let (line = ())
while {!~ <={line = <=%read} ()} {
$lambda $line
}
}
; cat input
one two
three
four
; %readfrom _devfdz {cat input} {{for-each @ l{ accum = $accum $l }} < $_devfdz}
; for (line = $accum)
echo $line
one two
three
four
I guess my point is that the benefit does not seem worth the trouble involved in modifying the yacc grammar to be able to obtain
%open 0 <={%one
!NODE:nredir($_devfdX {%readfrom _devfdX input PLACEHOLDER})
} {cmd}
and subsequently rewrite it to
%readfrom _devfdX input {
%open 0 <={%one $_devfdX} cmd
}
The same would also need to be done for %writeto _devfdX output
with %create 1
as well to get cmd > >{output}
working of course.
I certainly agree that the syntax and general behavior of the shell is currently too limited to allow for the desired behavior, but i imagine that's one of the best reasons why the functions are available in es: they allow you to do things that otherwise aren't possible. With es, you're not at the mercy of the shell's syntax and behaviors.
This seems like syntax that should be valid, right? Minimal (useless) example:
Found while thinking about alternatives to https://github.com/wryun/es-shell/pull/55.