sunilsurana
sunilsurana

Reputation: 133

Logging the last command and its output in bash

I want to retrieve the last executed command and its output in bash. I want that for every command executed on bash it automatically redirect output to a log file without actually adding riderection to command itself. Can we make any changes to bashrc to support this. I tried adding this to end of bashrc but it appends all the commands and its output to log.

exec > >(tee -a ~/.bash_command_log) 2>&1

I want to retain just the last one. What changed need to be done here

I want this because after executing a command my machine is supposed to automatically shutdown so when i start back i want to know the output of command

Upvotes: 0

Views: 158

Answers (1)

Socowi
Socowi

Reputation: 27330

exec > >(command) starts command and keeps it running as long as the bash session is running. Therefore, your tee "appends" the output of all commands to your log file, no matter whether you specify -a (append) or not. tee is only receiving one endless input stream, and cannot tell (and does not care) where the output of individual commands starts and ends.

Use PROMPT_COMMAND to start a new tee after the last command:

cmdlogprefix=~/.bash_command_log
cmdlogger() {
    mv "$cmdlogprefix"{.tmp,} &> /dev/null || true
    exec &> >(tee "$cmdlogprefix".tmp)
}
PROMPT_COMMAND+=(cmdlogger)

However, there are many problems:

  • Each tee command keeps running till the end of the bash session. You have to explicitly close their input streams. I skipped this part for brevity. *
  • exec > ... makes interactive programs like nano and htop unusable. This goes for other shells too. E.g. when starting bash from within your logged bash, you don't get a prompt.
  • Background jobs (cmd &) may overwrite/mangle the log file.
  • If you want to use exec normally, you (accidentally) stop logging for one command, and the PROMPT_COMMAND may collide with your planned use-case for exec.

You could improve above logger to alleviate some of these problems (* see above). But I would advise to have a look at dedicated solutions like the script command instead. Maybe you can combine script with logrotate's copytruncate to prevent clogging up your system with log files.

Upvotes: 2

Related Questions