73
Use process substitution with & redirection and exec:
exec &> >(tee -a "$log_file")
echo "This will be logged to the file and to the screen"
$log_file will contain the output of the script and any subprocesses, and the output will also be printed to the screen.
>(...) starts the process ... and returns a file representing its standard ...
answered Jul 21 '14 at 8:19
Michael Homer
63.4k1212 gold badges178178 silver badges206206 bronze badges
35
I want to see output of first command in terminal, and save the output of the second command in a file.
As long as you don't care whether what you are looking at is from stdout or stderr, you can still use tee:
myscript | tee /dev/stderr | grep -P 'A|C' > out.file
Will work on linux; I don't know if "/dev/stderr" is equally applicable on other *nixes.
answered Apr 6 '13 at 18:15
goldilocks
76.3k2323 gold badges181181 silver badges234234 bronze badges
35
When tee terminates, the command feeding it will continue to run, until it attempts to write more output. Then it will get a SIGPIPE (13 on most systems) for trying to write to a pipe with no readers.
If you modify your script to trap SIGPIPE and take some appropriate action (like, stop writing output), then you should be able to have it continue after tee ...
34
The structure :w !cmd means "write the current buffer piped through command". So you can do, for example :w !cat and it will pipe the buffer through cat.
Now % is the filename associated with the buffer
So :w !sudo tee % will pipe the contents of the buffer through sudo tee FILENAME. This effectively writes the contents of the buffer out to the file.
28
You could use a combination of GNU stdbuf and pee from moreutils:
echo "Hello world!" | stdbuf -o 1M pee cmd1 cmd2 cmd3 > output
pee popen(3)s those 3 shell command lines and then freads the input and fwrites it all three, which will be buffered to up to 1M.
The idea is to have a buffer at least as big as the input. This way even though the three ...
answered Mar 4 '13 at 22:08
Stéphane Chazelas
404k7171 gold badges795795 silver badges12071207 bronze badges
24
You could use named pipes (http://linux.die.net/man/1/mkfifo) on the command line of tee and have the commands reading on the named pipes.
mkfifo /tmp/data0 /tmp/data1 /tmp/data2
cmd0 < /tmp/data0 & cmd1 < /tmp/data1 & cmd2 < /tmp/data2 &
command -option1 -option2 argument | tee /tmp/data0 /tmp/data1 /tmp/data2
When command finishes, ...
21
sometimes /dev/tty can be used for that...
ls /bin /usr/bin | sort | uniq | tee /dev/tty | grep out | wc
19
I'm assuming that the pipeline of yours is running for a long time and that you are trying to remove the log file while it's running.
When you delete the file, the tee process still has it open for writing, which means that the disk space is not handed back to the system. That won't happen until all open file descriptors that references the file are closed. ...
answered May 29 '17 at 14:25
19
It's straightforward in shells that support process substitution, e.g. bash
$ echo foo | tee >(xsel)
foo
$ xsel -o
foo
Otherwise, you could use a FIFO (although it lacks convenience)
$ mkfifo _myfifo
$ xsel < _myfifo &
$ echo bar | tee _myfifo
bar
$ xsel -o
bar
[1] + Done xsel 0<_myfifo
$
answered Jun 17 '17 at 19:12
steeldriver
59.1k1010 gold badges7474 silver badges118118 bronze badges
18
tee always writes to its standard output. If you want to send the data to a command in addition to the terminal where the standard output is already going, just use process substitution with that command. (Note that in spite of starting with >, process substitution does not redirect standard output, the tee command sees it as a parameter.)
fortune | tee &...
answered Mar 31 '16 at 0:48
Gilles 'SO- stop being evil'
668k162162 gold badges13941394 silver badges18951895 bronze badges
17
You want the -a option to tee which appends rather than overwriting.
17
tee can duplicate to the current console by using tee /dev/tty
git status --short | cut -b4- | tee /dev/tty | xargs gvim --remote
Alteratively, you can use /dev/stdoutor /dev/stderr but they could be redirected if your command is within a script. Note that /dev/tty will always be the console (and may not exist in a non-interactive shell). This is wrong, ...
15
If I understand correctly, you're looking for the equivalent of tee file1 file2 file3, but rather than write the same data to three files file1, file2 and file3, you want to pipe the same data into three commands cmd1, cmd2 and cmd3, i.e.
… | ??? cmd1 cmd2 cmd3
should be equivalent to
… | cmd1 &
… | cmd2 &
… | cmd3 &
except that … would only ...
answered Mar 8 '15 at 22:22
Gilles 'SO- stop being evil'
668k162162 gold badges13941394 silver badges18951895 bronze badges
14
From the tee manual on my system:
The tee utility copies standard input to standard output, making a copy
in zero or more files. The output is unbuffered.
So, it reads from standard input and copies it to standard output, and while doing so also duplicates the stream into one or several files.
In the following pipeline, tee would take the output ...
answered Apr 29 '17 at 10:45
13
Yes, it slows things down. And it basically does have a queue of unwritten data, though that's actually maintained by the kernel—all programs have that, unless they explicitly request otherwise.
For example, here is a trivial pipe using pv, which is nice because it displays transfer rate:
$ pv -s 50g -S -pteba /dev/zero | cat > /dev/null
50GiB 0:00:...
13
Your assumption:
fortune | tee >(?stdout?) | pbcopy
won't work because the fortune output will be written to standard out twice, so you will double the output to pbcopy.
In OSX (and other systems support /dev/std{out,err,in}), you can check it:
$ echo 1 | tee /dev/stdout | sed 's/1/2/'
2
2
output 2 twice instead of 1 and 2.
You must use other file ...
13
If you want to recover the file blocks, you need to blank the file, not unlink it:
This portable way should work with most shells :
: > /media/pi/KINGSTON/klima.out
Unlinking the file (i.e. rm) is removing the directory entry but doesn't affect the file contents (inode) as long as the file is kept open by readers or writers.
13
The direct analogue of "tee for commands" is the pee command from moreutils (tee, but with pipes). Its arguments are used as commands to run, not as paths, and they get the input piped to them rather than written to file. All of the commands are given the standard input you piped to pee as their own.
Using pee, you can get the result you wanted by telling ...
answered Jun 17 '17 at 23:11
Michael Homer
63.4k1212 gold badges178178 silver badges206206 bronze badges
12
Your pipe commands, as a non-terminal destination, are buffering your output. It will show up eventually, but only when quite a lot of output builds up or the ping command exits.
You can use ping -c 5 google.com to set a specific number of packets to be sent and then ping will exit. Your output comes back and the pipes should work as expected.
Edit: ...
11
You need to give it some cache when playing from stdin
cat /dev/video1 | mplayer -cache 1024 -
Without that cache option you'll get the error
"Seek failed
Cannot seek backward in linear streams"
11
sudo tee -a /etc/ansible/hosts <myfile.txt >/dev/null
Or, if you want to use cat:
cat myfile.txt | sudo tee -a /etc/ansible/hosts >/dev/null
Either of these should work. It is unclear how you "added" /dev/null when you tried, but this redirects the standard output of tee to /dev/null.
answered Apr 9 '18 at 13:05
11
There's no difference in the sense that the data in the file will be the same if echo and tee are executed successfully and if the file is writable by the current user.
The tee command would additionally produce output on its standard output, showing the text that would also be appended to the file. This would not happen in the first command.
Another ...
answered Aug 24 '18 at 14:27
10
Simply pipe bash to tee. Or did I misunderstand the problem?
root@el6 ~ # cat test.sh
date
root@el6 ~ # cat test.sh | bash | tee >(logger -t "test")
Wed Jul 10 23:08:03 NZST 2013
root@el6 ~ # tail -n3 /var/log/messages
Jul 10 23:08:03 el6 test: Wed Jul 10 23:08:03 NZST 2013
10
It's an old post but I just found it now...
Instead of redirecting the output to > /dev/null you can redirect it to the last file:
echo "foobarbaz" | tee file1 > file2
Or for appending the output:
echo "foobarbaz" | tee -a file1 >> file2
9
{ ... | tee /dev/fd/3 | grep -e A -e C > out.file; } 3>&1
Or with process substitution (ksh93, zsh or bash):
... | tee >(grep -e A -e C > out.file)
With zsh:
... >&1 > >(grep -e A -e C > out.file)
answered Apr 6 '13 at 19:45
Stéphane Chazelas
404k7171 gold badges795795 silver badges12071207 bronze badges
9
The reason you are seeing the output of the original command is because tee outputs to stdout as well as the files specified. To discard this you can put >/dev/null at the end of the command or redirect this output to one of your process substitutions by adding an extra >, eg:
command | tee >(sed -rn 's/.*foo (bar).*/1/p') > >(awk '{print $3}'...
9
I think I’ve figured out how to tweak your experience
to turn it into something other people will be able to reproduce:
$ (echo hello; sleep 1; echo world) | tee >(cat)
hello
hello … and, after a brief delay,
world
world
$ echo "$?"
0
$ (echo hello; sleep 1; echo world) | tee >(echo yo)
yo
hello
$ ...
answered Apr 4 '16 at 5:25
G-Man Says 'Reinstate Monica'
18.1k1212 gold badges4949 silver badges101101 bronze badges
8
You need to add stdbuf(1) into your pipeline:
tail -f general.log | stdbuf -oL grep Some_word | tee -a todel.txt
This will set grep's stdout stream buffering mode to be line-buffered, otherwise grep waits to get at least 4096 bytes from the stream (this is the default on Linux for buffered i/o).
Alternatively, you can also call grep with --line-buffered:
...
8
In Bash, you can use process substitution with tee:
tee >(grep XXX > err.log) | grep -v XXX > all.log
This will put all lines matching XXX into err.log, and all lines into all.log. >( ... ) creates the process in the parentheses and connects its standard output to a pipe. This works in zsh and other modern shells too.
You can also use the pee ...
answered Jul 6 '14 at 22:11
Michael Homer
63.4k1212 gold badges178178 silver badges206206 bronze badges
Only top voted, non community-wiki answers of a minimum length are eligible
Related Tags
tee × 175bash × 71
pipe × 57
io-redirection × 34
shell-script × 28
stdout × 26
shell × 19
linux × 15
grep × 12
command-line × 10
cat × 10
process-substitution × 9
scripting × 8
sudo × 7
logs × 6
stderr × 6
text-processing × 5
stdin × 5
exec × 5
terminal × 4
echo × 4
netcat × 4
ubuntu × 3
ssh × 3
awk × 3