That's tee
you're searching for.
ls -l | tee outfile
prints the output of ls -l
to stdout (i.e. the terminal) and saves it in the file outfile
at the same time. But: It doesn't write the command name neither to stdout nor to the file. To achieve that, just echo
the command name before running the command and pipe both outputs to tee
:
( echo "ls -l" && ls -l ) | tee outfile
That's cumbersome to type, so why not define a function?
both(){ ( echo "$@" && "$@" ) | tee outfile ;}
After that you can just run
both ls -l
to get the desired result. Put the function in your ~/.bashrc
to have it defined in every new terminal.
If you want to be able to specify the output file as the first argument like in
both output ls -l
instead make it:
both(){ ( echo "${@:2}" && "${@:2}" ) | tee "$1" ;}
If you don't want the output file to be overwritten but rather append to it, add the -a
option to tee
.