Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Saving current directory to bash history

Tags:

bash

I'd like to save the current directory where the each command was issued alongside the command in the history. In order not to mess things up, I was thinking about adding the current directory as a comment at the end of the line. An example might help:

$ cd /usr/local/wherever $ grep timmy accounts.txt 

I'd like bash to save the last command as:

grep timmy accounts.txt # /usr/local/wherever 

The idea is that this way I could immediately see where I issued the command.

like image 606
Lajos Nagy Avatar asked Jun 03 '09 15:06

Lajos Nagy


People also ask

How do I keep bash history?

bash_history exists. If it does not, there's nowhere for bash to save command history. this just creates the empty . bash_history file in your home directory, which will fill up with your commands, and should persist between sessions.

What is bash history file?

File created by Bash, a Unix-based shell program commonly used on Mac OS X and Linux operating systems; stores a history of user commands entered at the command prompt; used for viewing old commands that have been executed. BASH_HISTORY files are hidden files with no filename prefix.

Where is bash history stored?

In Bash, your command history is stored in a file ( . bash_history ) in your home directory.

How do I view bash history?

The command is simply called history, but can also be accessed by looking at your . bash_history in your home folder. By default, the history command will show you the last five hundred commands you have entered.


1 Answers

One-liner version

Here is a one-liner version. It's the original. I've also posted a short function version and a long function version with several added features. I like the function versions because they won't clobber other variables in your environment and they're much more readable than the one-liner. This post has some information on how they all work which may not be duplicated in the others.

Add the following to your ~/.bashrc file:

export PROMPT_COMMAND='hpwd=$(history 1); hpwd="${hpwd# *[0-9]*  }"; if [[ ${hpwd%% *} == "cd" ]]; then cwd=$OLDPWD; else cwd=$PWD; fi; hpwd="${hpwd% ### *} ### $cwd"; history -s "$hpwd"' 

This makes a history entry that looks like:

rm subdir/file ### /some/dir 

I use ### as a comment delimiter to set it apart from comments that the user might type and to reduce the chance of collisions when stripping old path comments that would otherwise accumulate if you press enter on a blank command line. Unfortunately, the side affect is that a command like echo " ### " gets mangled, although that should be fairly rare.

Some people will find the fact that I reuse the same variable name to be unpleasant. Ordinarily I wouldn't, but here I'm trying to minimize the footprint. It's easily changed in any case.

It blindly assumes that you aren't using HISTTIMEFORMAT or modifying the history in some other way. It would be easy to add a date command to the comment in lieu of the HISTTIMEFORMAT feature. However, if you need to use it for some reason, it still works in a subshell since it gets unset automatically:

$ htf="%Y-%m-%d %R "    # save it for re-use $ (HISTTIMEFORMAT=$htf; history 20)|grep 11:25 

There are a couple of very small problems with it. One is if you use the history command like this, for example:

$ history 3 echo "hello world" ### /home/dennis ls -l /tmp/file ### /home/dennis history 3 

The result will not show the comment on the history command itself, even though you'll see it if you press up-arrow or issue another history command.

The other is that commands with embedded newlines leave an uncommented copy in the history in addition to the commented copy.

There may be other problems that show up. Let me know if you find any.

How it works

Bash executes a command contained in the PROMPT_COMMAND variable each time the PS1 primary prompt is issued. This little script takes advantage of that to grab the last command in the history, add a comment to it and save it back.

Here it is split apart with comments:

hpwd=$(history 1)              # grab the most recent command hpwd="${hpwd# *[0-9]*  }"      # strip off the history line number if [[ ${hpwd%% *} == "cd" ]]   # if it's a cd command, we want the old directory then                           #   so the comment matches other commands "where *were* you when this was done?"     cwd=$OLDPWD else     cwd=$PWD fi hpwd="${hpwd% ### *} ### $cwd" # strip off the old ### comment if there was one so they                                 #   don't accumulate, then build the comment history -s "$hpwd"             # replace the most recent command with itself plus the comment 
like image 52
Dennis Williamson Avatar answered Sep 27 '22 22:09

Dennis Williamson