New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Syntax improvements for redirection & pipes #110
Comments
I ran into this issue almost immediately so I'd love to see a solution. |
Can anyone give or link to an exact description of how bash handles the interaction of redirections and pipes? I can't find it in the bash reference manual. I always thought the bash equivalent of the o.p.'s command would give the same result as fish, but it turns out that My (apparently wrong) mental model of redirection in bash is that
|
In the manual for Bash under Pipelines i found this: So the redirection would be like this if my understanding is correct:
It is possible to do this today in fish using special syntax I did a few trials using fish, bash and tcsh (note that my tcsh dont support to only redirect stderr, as noted in that cmd):
|
My expectation would be that |
I like the Proposal:
|
The good thing is that the syntax is beginning to look like a fish ... |
Let’s try to fix this one in next-minor |
If you can pipe stdout and stderr independently, how do pipes associate? For example:
Does baz get the output of foo or bar? Anyone know how other shells handle this? |
If we had subshells, I assume the answer would be that you'd need to do the following if you want stderr to go through multiple processes:
stderr goes through Is there any subshell-like thing in fish? I often want to do stuff in another dir temporarily, which I used to do in bash with |
@gfxmonk: But we do. foo ^| begin
bar | baz
end | frob |
@glitchmr that's brilliant |
It sounds like the proposed answer to my question is that a stderr-only pipe would be standalone, and not part of the larger pipeline. That is, |
This has been a serious issue for me too so I'd love to see a solution too. @glitchmr that looks very fishy! |
With the commit 4899086 , the original problem I want to leave this open for further discussion on syntax improvements for redirections. The current thinking is that |
My high order bit is that syntax for common redirections should be easy to learn and to remember. In particular, no common redirections should require using numbers. Here are four proposals for piping stdout and stderr together:
Individual discussion:
|
If to think of '|' as only of redirection symbol with default pipe = stdout, but with possibility to override it the scheme would be the following:
Arguments for:
Arguments against:
|
@maxfi 's proposal is probably more coherent by its usage of both symbols to represent both redirection, but I somehow don't like it and I'd rather have the ^| @ridiculousfish proposed. If ^| were to redirect both stdout and stderr, would one redirect only stderr by using something like:
? |
@anddam stderr can be piped separately via |
Debian bug 520363 was concerned with the original behaviour. |
It looks like |
…the redirections for a process were flattened into a big list associated with the job, so there was no way to tell which redirections applied to each process. Each process therefore got all the redirections associated with the job. See fish-shell#877 for how this could manifest. With this change, jobs only track their block-level redirections. Process level redirections are correctly associated with the process, and at exec time we stitch them together (block, pipe, and process redirects). This fixes the weird issues where redirects bleed across pipelines (like fish-shell#877), and also allows us to play with the order in which redirections are applied, since the final list is constructed right before it's needed. This lets us put pipes after block level redirections but before process level redirections, so that a 2>&1-type redirection gets picked up after the pipe, i.e. it should fix fish-shell#110 This is a significant change. The tests all pass. Cross your fingers.
I really don't understand this, if you try to create something less cryptic than bash, then what's wrong with:
Can do away with the magic numbers and symbols. I would keep '>' and '>>' because that's pretty intuitive, although the difference between the two is still something that has to be learned and remembered. And I would keep '|' because it is so universally used and known, at least on *nix based systems.
|
To summarize for anyone who comes here researching how to do this after me: You can send stderr to stdout in either of these two ways: # use the bash syntax (output is out of order b/c Ruby buffers stdout)
> ruby -e '$stdout.puts "a"; $stderr.puts "b"' 2>&1 | ruby -e 'puts "PIPED: #{$stdin.read.inspect}"'
PIPED: "b\na\n"
# redirect stderr to stdout's file descriptor (in the subshell, it's connected to the pipeline)
> ruby -e '$stdout.puts "a"; $stderr.puts "b"' ^/dev/stdout | ruby -e 'puts "PIPED: #{$stdin.read.inspect}"'
PIPED: "b\na\n" And you can send stderr to the pipe instead of stdout by using # normal: err goes to process's err (prints to screen), out goes through pipeline
> ruby -e '$stdout.puts "a"; $stderr.puts "b"' | ruby -e 'puts "PIPED: #{$stdin.read.inspect}"'
b
PIPED: "a\n"
# with ^|, err goes into pipelline, out goes to process's out (prints to screen)
> ruby -e '$stdout.puts "a"; $stderr.puts "b"' ^| ruby -e 'puts "PIPED: #{$stdin.read.inspect}"'
a
PIPED: "b\n" |
Just a thought: Bash uses So I propose that fish use So these would be equivalent: Bash:
Fish:
|
function foo
echo stdout
echo >&2 stderr
end
foo ^&1 | tee out # out contains both lines of output This works for me today (version 2.2.0). Both stdout and stderr get piped to tee. I tested with a little C program as well and it still worked. Maybe this should be closed? |
Doing @gustafj's test, I now get: > cmd | cat - >/dev/null
stderr
> cmd 2>| cat - > /dev/null # all "2>" can also be replaced with "^"
stdout
> cmd 2>| cat -
stdout
stderr
> cmd 2>&1 | cat - > /dev/null
> This means it's okay since probably 4899086. However, as @ridiculousfish pointed out:
Personally, I don't really care. Because of the repurposing of this issue, I'll change the title to something more fitting. |
I'd like it if something like |
@onodera-punpun what about the current ^> stderr redirection? Adding a new >^ syntax would indeed be confusing. |
@anddam What? |
@anddam tbh I never know, I'm pretty sure it's either |
@solson correct, I mixed up the syntax (that I've been using till an hour ago) and somehow thought ^ was ^> in fact. My bad and sorry for the noise. Anyway as a general principle I wouldn't overload too much combinations of > ^ and so, I'd rather have a more verbose but clear syntax than having to check man every time (as in fact I did with bash and what made me look for a shell with a tidier syntax). |
To summarize the current suggestions:
Using both combinations for each case solves the problem of having to remember the order of the characters. In a sense they mirror each other and seem to make sense. However, the piping syntax is definitely a Bashism. So even though I generally favor it, let me add a third suggestion:
However, this also raises the question of whether something like And that actually seems like it could be pretty handy; it sure saves a lot of typing in that case and is much clearer as to its purpose. It would also help avoid the issue of redirecting STDERR and STDOUT in the wrong order, which is a common gotcha, as doing |
@alphapapa
I would support having |
Well, how about that! :D
I'd just like to point out how fishy some of those look, which I hope could be preserved in the docs somehow... ;) Or maybe we could go all-in and have |
could someone add an answer on http://unix.stackexchange.com/q/70963/50703 with what the fish equivalents are for each one, cheers - as I'm having a hard time figuring out what are proposals here and what is implemented, and then for the implemented stuff, what they actually do |
fish has the same syntax for all of those cases, except that |
@ridiculousfish yeah - I was wrestling with |
with my above answer, the |
Being that #4394 has removed How about, to redirect multiple file descriptors to the same file, we extend the syntax to allow a list of file descriptors into the redirection operator? To redirect both stdout and stderr to the same file, it would simply be Of course, this cannot actually "expand" to This applies similarly in the case of redirection-into-pipe: In discussion above, @ridiculousfish's take is that "no common redirections should require using numbers". But with the removal of Discussion in this thread supports (And if we really wanted to save another character, then |
A bit late, but a note for @balupton, you can get it to work for files with $ bash -c 'echo out; echo err >&2' > file ^ /dev/stdout`
$ cat file
out
err |
What is the status of this now that #4394 landed in v3 |
Yup, this should be closed. An overview of the current situation:
|
Should I open a new issue with my suggestion then? I think it's an interesting idea for extending the redirection syntax |
Honestly, I don't think shortcuts are needed here. Which is also why we stepped away from If you want to redirect both stdout and stderr, use |
Well, I like the |
I have been reading several of these issues, and I still cannot figure out how to redirect both stdout and stderr into tee in the fish shell. |
@frankseide In fish 3.1 Otherwise So: whatever 2>&1 | tee
# or
whatever &| tee In future, please don't comment on random issues. Instead open a new one or ask on https://gitter.im/fish-shell/fish-shell. |
Assuming I have a process that writes to both stderr and stdout, and I want to pipe both to tee, I should be able to do:
./a.out ^&1 | tee log
This ends up with 'log' being empty.
I suspect that fish is assigning the stderr input stream to the stdout sink, then assigning the stdout input stream to the pipe sink. Another layer of indirection would likely solve this -- instead of copying the stdout sink, you assign a wrapper sink instead. This would require caution to catch the case of redirecting >&2 ^&1, of course, but it would allow people to redirect and pipe at the same time and make it work.
The text was updated successfully, but these errors were encountered: