4

If I wanted to have the output of the last command stored in a file such as ~/.last_command.txt (overwriting output of previous command), how would I go about doing so in bash so that the output goes to both stdout and that file? I imagine it would involve piping to tee ~/.last_command.txt but I don't know what to pipe to that, and I definitely don't want to add that to every command I run manually.

Also, how could I extend this to save the output of the last n commands?

iobender
  • 3,346
  • 1
  • 17
  • 21
  • You should maybe explain _why_ you want to do that. We might come with a better solution than focusing only on _how_ you approached the problem so far. – Sylvain Leroux Jul 25 '14 at 12:05
  • A somewhat similar question, but for tcsh: http://stackoverflow.com/q/15056573/2096752 – shx2 Jul 25 '14 at 12:07
  • You're better off doing this in the terminal program where you run your shell rather than doing this directly in the shell itself. I can see a solution which may work 99.9% of the time, but it's that last .01% that will turn out to be an absolute disaster. All it takes is one program that's manipulating the file descriptors in a weird and wacky way that conflicts with the weird and wacky way you'd have to manipulate the file descriptors. – David W. Jul 25 '14 at 12:14

4 Answers4

1

Under bash this seems to have the desired effect.

bind 'RETURN: "|tee ~/.last_command.txt\n"'

You can add it to your bashrc file to make it permanent.

I should point out it's not perfect. Just hitting the enter key and you get:

matt@devpc:$ |tee ~/.last_command.txt
bash: syntax error near unexpected token `|'

So I think it needs a little more work.

hookenz
  • 36,432
  • 45
  • 177
  • 286
  • This is the wrong approach; many commands (`while` and `for` loops, `if` statements, etc.) span multiple lines, so you don't want to add a pipe after each line. – chepner Jul 23 '14 at 05:11
  • This does work as you mentioned, but has a few drawbacks. The one you mentioned, for one. It also removes formatting such as color and lack of line breaks from stuff like `ls`. Prefixing a command with `unbuffer` will add this, but that means the alias for `ls --color` doesn't work and I have to specify `--color`. Lastly, it make for a very ugly terminal session, to look at the commands you just type and the output of `history`. I hope bash has a better way of dealing with this. – iobender Jul 23 '14 at 05:18
0

This will break program/feature expecting a TTY, but...

exec 4>&1
PROMPT_COMMAND="exec 1>&4; exec > >(mv ~/.last_command{_tmp,}; tee ~/.last_command_tmp)"

If it is acceptable to record all output, this can be simplified:

exec > >(tee ~/.commands)
Sylvain Leroux
  • 50,096
  • 7
  • 103
  • 125
0

When starting a new session (after login, or after opening the terminal), you can start another "nested" shell, and redirect its output:

<...login...>
% bash | tee -a ~/.bash_output
% ls  # this is the nested shell
% exit
% cat ~/.bash_output
% exit

Actually, you don't even have to enter a nested shell every time. You can simply replace your shell-command in /etc/passwd from bash to bash | tee -a ~USERNAME/.bash_output.

shx2
  • 61,779
  • 13
  • 130
  • 153
0

Overwrite for 1 command:

script -c ls ~/.last_command.txt

If you want more than 1 command:

$ script ~/.last_command.txt
$ command1
$ command2
$ command3
$ exit

If you want to save during 1 login session, append "script" to .bashrc

Walter A
  • 19,067
  • 2
  • 23
  • 43