Saving current directory to bash history

后端 未结 9 1853
时光取名叫无心
时光取名叫无心 2020-11-28 19:29

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

相关标签:
9条回答
  • 2020-11-28 19:57

    For those who want this in zsh I've modified Jeet Sukumaran's implementation and percol to allow interactive keyword searching and extraction of either the command or path it was executed in. It's also possible to filter out duplicate commands and hide fields (date, command, path)

    0 讨论(0)
  • 2020-11-28 20:00

    You could install Advanced Shell History, an open source tool that writes your bash or zsh history to a sqlite database. This records things like the current working directory, the command exit code, command start and stop times, session start and stop times, tty, etc.

    If you want to query the history database, you can write your own SQL queries, save them and make them available within the bundled ash_query tool. There are a few useful prepackaged queries, but since I know SQL pretty well, I usually just open the database and query interactively when I need to look for something.

    One query I find very useful, though, is looking at the history of the current working directory. It helps me remember where I left off when I was working on something.

    vagrant@precise32:~$ ash_query -q CWD
    session
        when                   what
    1
        2014-08-27 17:13:07    ls -la
        2014-08-27 17:13:09    cd .ash
        2014-08-27 17:16:27    ls
        2014-08-27 17:16:33    rm -rf advanced-shell-history/
        2014-08-27 17:16:35    ls
        2014-08-27 17:16:37    less postinstall.sh
        2014-08-27 17:16:57    sudo reboot -n
    

    And the same history using the current working directory (and anything below it):

    vagrant@precise32:~$ ash_query -q RCWD
    session
        where
            when                   what
    1
        /home/vagrant/advanced-shell-history
            2014-08-27 17:11:34    nano ~/.bashrc
            2014-08-27 17:12:54    source /usr/lib/advanced_shell_history/bash
            2014-08-27 17:12:57    source /usr/lib/advanced_shell_history/bash
            2014-08-27 17:13:05    cd
        /home/vagrant
            2014-08-27 17:13:07    ls -la
            2014-08-27 17:13:09    cd .ash
        /home/vagrant/.ash
            2014-08-27 17:13:10    ls
            2014-08-27 17:13:11    ls -l
            2014-08-27 17:13:16    sqlite3 history.db
            2014-08-27 17:13:43    ash_query
            2014-08-27 17:13:50    ash_query -Q
            2014-08-27 17:13:56    ash_query -q DEMO
            2014-08-27 17:14:39    ash_query -q ME
            2014-08-27 17:16:26    cd
        /home/vagrant
            2014-08-27 17:16:27    ls
            2014-08-27 17:16:33    rm -rf advanced-shell-history/
            2014-08-27 17:16:35    ls
            2014-08-27 17:16:37    less postinstall.sh
            2014-08-27 17:16:57    sudo reboot -n
    

    FWIW - I'm the author and maintainer of the project.

    0 讨论(0)
  • 2020-11-28 20:02

    Gentleman this works better.. The only thing I can not figure out is how to make the script NOT log to syslog on login and log the last command in history. But works like a charm so far.

    #!/bin/bash
    
    trackerbash() {
        # adds comments to bash history entries
    
        # by Dennis Williamson
        # http://stackoverflow.com/questions/945288/saving-current-directory-to-bash-history
        # (thanks to Lajos Nagy for the idea)
    
        #Supper Enhanced by QXT
    
    
        # INSTALLATION: source this file in your .bashrc
    
        export HISTTIMEFORMAT=
    #    export HISTTIMEFORMAT='%F   %T    '
    
        local hcmnt
        local cwd
        local extra
        local thistty
        local whoiam
        local sudouser
        local shelldate
        local TRACKIP
        local TRACKHOST
    
    
                thistty=`/usr/bin/tty|/bin/cut -f3-4 -d/`
                whoiam=`/usr/bin/whoami`
                sudouser=`last |grep $thistty |head -1 | awk '{ print $1 }' |cut -c 1-10`
                hcmnt=$(history 1)
                hcmnt="${hcmnt# *[0-9]*  }"
                cwd=`pwd`
    
    
    
                hcmnt="${hcmnt% ### *}"
                hcmnt=" $hcmnt ${extra:+$extra }"
    
                shelldate=`date +"%Y %b %d %R:%S"`
                TRACKHOST=`whoami | sed -r "s/.*\((.*)\).*/\\1/"`
                TRACKIP=`last |grep $thistty |head -1 | awk '{ print $3 }'`
    
    
                logger -p local1.notice -t bashtracker -i -- "$sudouser ${USER}: $thistty: $TRACKIP: $shelldate: $cwd : $hcmnt"
                history -w 
    
    }
    export PROMPT_COMMAND='trackerbash'
    
    
    0 讨论(0)
  • 2020-11-28 20:08

    Here's a one liner of what I use. Sticking it here because it's vastly simpler, and I have no problem with per-session history, I just also want to have a history with the working directory.

    Also the one-liner above mucks with your user interface too much.

    export PROMPT_COMMAND='if [ "$(id -u)" -ne 0 ]; then echo "$(date "+%Y-%m-%d.%H:%M:%S") $(pwd) $(history 1)" >> ~/.bash.log; fi'
    

    Since my home dir is typically a cross-mounted gluster thingy, this has the side effect of being a history of everything I've ever done. Optionally add $(hostname) to the echo command above... depending on your working environment.

    Even with 100k entries, grep is more than good enough. No need to sqlite log it. Just don't type passwords on the command line and you're good. Passwords are 90's tech anyway!

    Also, for searching I tend to do this:

    function hh() {
        grep "$1" ~/.bash.log
    }
    
    0 讨论(0)
  • 2020-11-28 20:10

    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
    
    0 讨论(0)
  • 2020-11-28 20:10

    You could consider an independent project (I wrote it) that supports saving the path for each command: https://github.com/chrissound/MoscoviumOrange

    Where you can add a hook into Bash to save each entry with:

    $(jq -n --arg command "$1" --arg path "$PWD" '{"command":$command, "path":$path}' | "$(echo 'readlink -f $(which nc)' | nix run nixpkgs.netcat)" -N -U ~/.config/moscoviumOrange/monitor.soc &)
    
    0 讨论(0)
提交回复
热议问题