Using bash on OSX. How can I set up my shell so that it overwrites a certain file with the output of my most recent command? This would be really convenient for viewing/searching/analyzing large outputs that I didn't have the foresight to pipe to a file. Thanks for the help!
问题:
回答1:
Use script
and your commands and their output are stored in a log file until you exit from script
.
script mylogfile.output
After running this command, you are back at the bash command prompt and you can continue your bash session as normal. All commands and ouput are saved to "mylogfile.output".
You could put this in your ~/.bashrc file so it starts automatically as follows:
[ -n "$PS1" -a -z "$SCRIPT_STARTED" ] || export SCRIPT_STARTED=$$
[ "$SCRIPT_STARTED" -eq $$ ] && script -q ~/mylogfile.output
The "-q" option makes it start quietly which is safer for ~/.bashrc
commands.
回答2:
You can't save the output of the last command verbatim without re-running the command, but you can mark the contents of the terminal with the mouse and paste it to a file with the middle mouse button (or Shift+Insert) in most terminals. To run the command again and save standard ouput, you can do this:
!! > command.log
To also save standard error to the same file:
!! > command.log 2>&1
回答3:
If you don't care about the file size produced you can easily do this:
bash | tee /tmp/bash.history.log
This command spawns a subshell and copies the stdout of that shell to the specified file. Of course, this file has everything in it and not just the most recent command. However, I assume this behaviour will probably be (like the script
answer given by @John1024) more helpful since you would have to be very careful not to enter another shell command after the one you are interested in since that action would actually overwrite it. :-)
If you want to have some kind of revolving history you might try the following (admittedly pretty clumsy) approach:
Create a named FIFO pipe
mkfifo /tmp/bash.history.fifo
Start a background process reading from that FIFO and splitting the output into the split command:
split -a 5 -u -b 1000000 /tmp/bash.history.fifo /tmp/bash.history.
Then start the subshell as before but use the FIFO as file target:
bash | tee /tmp/bash.history.fifo
This will give a sequence of files /tmp/bash.history.aaaaa
, /tmp/bash.history.aaaab
and so on of about 1MB size each. Now you can easily define a CRON job that cleans out all files that are older than e.g. 24 hours. This way you have the complete history of what you did over that time frame. Of course, you may have to look at more than file if an interesting output has been split.
And, as with proabably all solutions presented here, you may want to spend a second thought on security since all output piped to a standard file will probably be readable to others (given default umask for home directories). The latter issue may be addressed by moving the pipe and the log files to a sub directory of your home directory from which you remove read and execute permissions to other
and possibly also to group
.