6 ms·
I set up my bash config to store history separately for each working directory (ie separate history files that I store under a $HOME/.bash_history_d directory)
by aaronharnly 7y ago
I set up my bash config to store history separately for each working directory (ie separate history files that I store under a $HOME/.bash_history_d directory) – so as I cd into a project directory, the history is populated with the commands that I've run within that directory.
I find this super-helpful to remind me of the context for projects – cd in, then up-arrow to whatever that command is I usually run to launch this server, grep this logfile, etc.
There are some downsides – sometimes I want to run the same command in directory X and also in subdirectory X/Y, but I love doing it this way.
Anyone else done something similar?
- zwieback 7y agoThat's clever, I'd like that. Can you have another key to recall the global history, e.g. all the combined histories like you would normally see?
- dllthomas 7y agoI do something similar, but instead of current directory I have a notion of context that is carried by an environment variable set in a GNU screen process (and therefore inherited by its children) which drives logic in my .bashrc. https://github.com/dlthomas/config-files https://github.com/dlthomas/config-files
- dual_basis 7y agoFish does this by default (and much more as well).
- dllthomas 7y agoCould you elaborate? I can read docs, but it's not clear to me what correspondences you have in mind. Specifically, I'm not sure what "this" is that fish does, as I described interaction of multiple pieces of software and I don't think fish includes a terminal multiplexer?
- jackbravo 7y agoautocompletion in fish takes into account the directory where you are at, so it will autocomplete commands ran in the same directory before other commands.
- dllthomas 7y agoIf that's what's being referred to, it sounds like dual_base meant to reply to aaronharnly? As mentioned, my setup isn't based on working directory.
- dual_basis 7y agoOh, I see. I interpreted "context" as current working directory. I took a look at your .bashrc but I couldn't detemine any sort of partitioned history. Are you saying that you have something like a virtual environment (as in Python) and the bash command history is separated according to the environment?
- dllthomas 7y agoI split up my bashrc, pulling in different "component" files: https://github.com/dlthomas/config-files/blob/master/.bashrc#L95 https://github.com/dlthomas/config-files/blob/master/.bashrc... The history file is set here: https://github.com/dlthomas/config-files/blob/master/.bash.d/session.bashrc#L9 https://github.com/dlthomas/config-files/blob/master/.bash.d...
- dasl 7y agoI use zsh, and I have a thing in my profile that skips writing any `cd` command to history. Instead, it will rewrite the command using the absolute path of the directory I `cd`'d into and write that to history. Thus, all of the `cd` commands that get written to my history use absolute paths and are re-usable no matter where I am. It would be cool if this sort of functionality were generalizable to all commands where you type a relative path, not just `cd`. https://github.com/dasl-/settings/blob/3143bbfe23bd75c3e35c76350355fba2fe25fce8/.zshrc#L95-L114 https://github.com/dasl-/settings/blob/3143bbfe23bd75c3e35c7...
- smacke 7y agoYou might enjoy checking out 'fasd', which, among other things, creates an alias ('zz') with autocomplete functionality for changing to frequently-used directories. https://github.com/clvv/fasd https://github.com/clvv/fasd
- isatty 7y agoOr just github.com/rupa/z
- dual_basis 7y agoIn fish, suggested autocompletions are contextual. For example, if I am in /home/dual_basis/projectA and I type `cd some/subdir` then a bunch of time goes by when I come back to /home/dual_basis/projectA and start typing `cd` it will suggest `cd some/subdir`, even if I have typed a bunch of other `cd` commands while in other directories. This isn't specific to `cd` commands either. It's useful if you are `rsync`ing different directories to different places, or checkout different `git` branches, etc.
- tyingq 7y agoThat seems like it would be tricky for it not to screw something up. Like, for example, would it handle this properly? $ (cd /source;tar -cf - .) | (cd /dest;tar -xf -)
- Yen 7y agoI've done the same thing, and I've found it super helpful. My particular configuration is at https://github.com/YenTheFirst/dotfiles/blob/master/.bash_cd_hook.sh https://github.com/YenTheFirst/dotfiles/blob/master/.bash_cd... 90% of the time, the bash history is super relevant to the current context. A small amount of the time, I remember that I issued a command, but not in which directory - in these cases, I can just search the history directory, and get both the context of what the command was, and also where I was when I originally issued it.
- chubot 7y agoThanks, reading over that code was useful. In particular I realized that my Oil project (a bash-compatible shell [1]) doesn't support PROMPT_COMMAND, which tons of people appear to be using. https://github.com/oilshell/oil/issues/320 https://github.com/oilshell/oil/issues/320 It seems like a weird hack but apparently it works for tons of things! [1] Latest status: Success With the Interactive Shell http://www.oilshell.org/blog/2019/02/05.html http://www.oilshell.org/blog/2019/02/05.html . Oil runs a bunch of interactive programs like bash-completion, virtualenv, and git-prompt.
- inciampati 7y agoThis is lovely, and I should integrate it with the chronology based approach I've been using. I keep an infinite log by appending a timestamp to the beginning of the lines written to my history file, then merging this into a growing log with an hourly cronjob that runs sort -n | uniq on the file and the new version of the shell history. This way the shell history file is just a buffer. It doesn't get too big to cause corruption or other issues with reverse search on the command line. I just grep my way through the big history file to figure out what I was doing and when.
- GuB-42 7y agozsh-histdb stores history inside a sqlite database instead of a simple text file. The good thing is that it includes context: current directory, session, date. I use it together with ssh-suggestions which can use SQL queries to find the most relevant command. You can program rules such as: use the most frequent command in that session, if you none do it for the current directory in the last 6 months, if not, search globally.
- dudouble 7y agoThank you for this. It always amazes me when I come across something that would be so useful to me, and yet so obvious in hindsight.
- lscotte 7y ago> Anyone else done something similar? I'm not, but now that you mention this, I think I will. I already use direnv all over the place, and this would be a pretty natural extension. Thanks!
- _em_ 7y agoCould you share details on how did you setup this. This sounds super useful
- euske 7y agoI set PROMPT_CMD to the following function: function log_history { echo "`date '+%Y-%m-%d %H:%M:%S'` $HOSTNAME:$$ $PWD ($?) `history 1`" >> $MYHISTFILE } which records a timestamp, host name, shell pid, working directory and exit status for each command.
- unhammer 7y agoI use one bash history (and fasd history) per tmux session: https://gist.github.com/unhammer/abef48d8f6452c74e3513c6848577584 https://gist.github.com/unhammer/abef48d8f6452c74e3513c68485...
- narnianal 7y agoIt's a great idea. If you additionally also like working with chroots you might find containers an interesting topic. Basically a container let's you wrap a part of your filesystem, network, process space in a separate world of its own. And in that world you have only the context related stuff like history, processes, libs etc. Additionally most container environments come with tooling that enables you to make everything reproducable, so that you can share your container with others. The great thing is you can always live in global space, while switching between what that global space means.
- danappelxx 7y agoHow would one go about setting up a container?
- narnianal 7y ago`docker run <somethingyoulike>` for instance