10

How to get stdout to console and pipe to next command at the same time?

I've tried using the Read command as suggested here which worked to get the output of Grep from a Tail of a log file to a variable and then to a log or email, but I'd still like to get the output to stdout console as well: https://unix.stackexchange.com/a/365222/346155

I've tried using Tee as here: https://unix.stackexchange.com/a/47936/346155

I'm using the --line-buffered flag just in case from here: https://stackoverflow.com/a/7162898/4240654

I may be missing something simple about the sdtin logic, but the case from the first link suggests that Bash may not have this simple capability. And that variables cannot read from a subshell.

The fact that echo 'hello' | echo $(</dev/stdin) works, suggests it might be possible. Another way to look at it is, how can I stdout to console within each pipe segment. That should help to debug a long chain of commands, before committing it to a bash script.

EDITS: Something like echo 'hello' | echo $(</dev/stdin) >/dev/stout or echo 'hello' | tee >/dev/stdout | echo 2nd $(</dev/stdin), the latter should output 'hello' twice, but only does so once.

10
  • How did you use tee? Commented Mar 25, 2020 at 17:12
  • I was able to Tee to a log file, but not yet to Stdout console.
    – alchemy
    Commented Mar 25, 2020 at 17:17
  • Do you want this echo hello | tee >(grep -o h)? Commented Mar 25, 2020 at 17:28
  • @ArkadiuszDrabczyk In total I want it to (tail log) | grep "keyword" | tee>*OutToConsole* | (read var | echo var | mail ) so I can see the alert line also before it emails.....YES, that was what I was missing.. Grep in a subshell does stsout to console Thanks! .. for the record, so does Echo.
    – alchemy
    Commented Mar 25, 2020 at 17:32
  • tail log | grep "keyword" | tee >(mail)? Commented Mar 25, 2020 at 17:37

2 Answers 2

9

Use tee /dev/tty. Example:

echo "Hello word" | tee /dev/tty | wc -c

tee and /dev/tty are required by POSIX.


In general you can use a name like /dev/tty2 or /dev/pts/7. It doesn't have to be the current terminal, if only you can write to it.

Another way to look at it is, how can I stdout to console within each pipe segment. That should help to debug a long chain of commands, before committing it to a bash script.

I have done something similar conveniently with tmux panes. You can do this with or without tmux.

  1. Prepare as many panes as you need; or console windows, if you prefer.
  2. In each invoke tty to learn the filename of the terminal.
  3. In one of them invoke the pipeline you want to debug, using tee and a different terminal in each step. This pipeline

    command1 | command2 | command3
    

    will become something like

    command1 | tee /dev/pts/4 | command2 | tee /dev/pts/5 | command3
    

    where /dev/pts/4 and /dev/pts/5 are additional terminals (e.g. panes in tmux).

2
  • You can do that even when not run from a terminal { echo "Hello word" | tee /dev/fd/7 | wc -c; } 7>&1 (ok, not POSIX, and will NOT work on FreeBSD by default). Notice that /dev/tty or /dev/pts/N do not always work: su other_user -c 'echo hi | tee /dev/tty | wc -c' => tee: /dev/tty: No such device or address. But it's not clear for me that it's this that the OP is after ;-)
    – user313992
    Commented Mar 25, 2020 at 20:34
  • This is great, exactly what I was looking for! @mosvy, there may be special cases where it doesnt work, and good to know it will translate into a script. What is 7 again?
    – alchemy
    Commented Mar 26, 2020 at 3:10
1

... | tee log-file-name

This take the stdout of the first command and copies to the log file, and to stdout.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .