每个目录的bash / zsh历史记录日志文件


14

我发现我在固定目录中的项目上做了很多工作。有时-几个月后-我需要在该项目上重做一些事情,但我不记得自己做了什么。我使用mercurial或git跟踪文件更改,但我希望能够记住在该目录中发出的命令。

搜索我的shell历史记录不是很有帮助。我已经将所有内容都记录到了我的。* _ history文件中,但是我想要列出我在〜/ foo / bar中所做的事情的列表,而不是那一周我所做的所有其他(百万次)事情。我什至可能都不记得我上个月从事那个特定项目了。

有谁知道我使用过的所有shell命令的项目目录日志文件如何?我正在设想一个类似的命令:

我的项目

...这会将外壳程序日志文件设置为〜/ myproject / .history.log,从该日志文件加载以前的历史记录,并可能更新提示以告诉我正在使用的目录(例如vcprompt以提供版本)控制信息)。

那里有什么东西吗?

Answers:


4

如果您还没有弄清楚这一点:您正在寻找的是出色的virtualenvwrapper软件包。它是python的virtualenv(如图)的包装,尽管在使用python环境时通常被引用,但它实际上是一种非常通用的工具,可以满足您的用例。

安装

pip install virtualenvwrapper

要么

easy_install virtualenvwrapper

并将初始化内容添加到您的shell配置(~/.zshrc, ~/.bashrc)中

export WORKON_HOME=$HOME/.virtualenvs
export PROJECT_HOME=$WORKON_HOME/projects
export PIP_VIRTUALENV_BASE=$WORKON_HOME
export PIP_RESPECT_VIRTUALENV=true
source /usr/local/bin/virtualenvwrapper.sh

用法

# create your env
mkvirtualenv my_project

# edit per project hooks
vim ~/.virtualenvs/my_project/bin/{postactivate,preactivate,predeactivate,etc}

# work in this env
workon my_project

您还具有~/.virtualenvs/{postactivate,postdeactivate,etc}每次都被调用的通用钩子workon any_project

因此,例如,将行export HISTFILE="$VIRTUAL_ENV/bash_history"插入~/virtualenvs/postactivate钩子意味着$HISTFILE变量将每次都扩展到另一个项目。


3

我也需要这个,并且我想出了一个使用Bash的PROMPT_COMMAND变量的版本:

在Bash打印每个主提示之前,将检查变量PROMPT_COMMAND的值。如果设置了PROMPT_COMMAND且具有非空值,则将执行该值,就像在命令行上键入该值一样。

所以我说〜/ .bashrc.my中的PROMPT_COMMAND =“ check_for_local_history”,这check_for_local_history是我的一个函数,它检查最后执行的命令是否是目录更改,当它为true时,它将检查新的当前目录中的.bash_history文件。 。如果存在,请将其用作历史记录文件。

这是完整的要点:https : //gist.github.com/gurdiga/dac8d2e7eb3056d6b839


2

我用于为产品构建子包的框架的一个技巧是使用子外壳。

对于bash,您可以创建如下的shell脚本:

#!/bin/bash

export PROJECT_DIRECTORY=$(pwd)

exec bash --rcfile $HOME/.project-bashrc

然后在其中输入$HOME/.project-bashrc以下内容:

source $HOME/.bashrc
export HISTFILE="${PROJECT_DIRECTORY}/.bash_history"
cd "${PROJECT_DIRECTORY}"

这也使您可以自定义.project-bashrc文件中的提示,这很方便。

我不确定如何在中执行相同的操作zshZDOTDIR我认为您必须重写该变量。但这看起来很相似。

再见!


1

这里看看我的日志记录脚本。使用其中之一,您可以在发出每个命令时跟踪您所在的目录。您可以grep在日志文件中获取命令或其他信息。我在家和工作中都使用长版。


谢谢-我来看看。可能会做些接近我需要的事情!
西蒙(Simon)

1

您可能对我为zsh 编写的名为directory-history的插件感兴趣。
在这里查看:https : //github.com/tymm/directory-history

尽管它并不完全适合您在myproject工作流程中的工作,但它应该完全适合您的需求。

它创建一个包括目录的历史记录。
搜索历史记录时,首先会从所在目录中获取命令。
如果该目录中没有命令,它将回退到全局历史记录并建议其他目录中使用的命令。


1

如果您想简单一些,可以使用以下.history.log文件:

#!/bin/cat
some
relevant
commands

然后,将在文件中cat列出的那些命令运行该文件。
您还可以按照约定按照功能将这些命令分组在单独的文件中:

.howto.datadump
.howto.restart

这具有开箱即用且不污染环境的附加优势。


或者,您可以按主题使用README.md或创建其他.md文件,并从自述文件中指向它们。那就是如果您具有markdown友好的源代码管理界面。
里诺

1

为了获取目录的本地历史文件,我在bash提示命令中添加了以下行。

if [ -f .local_history ] ; then tail -1 $HISTFILE >> .local_history ; fi

然后touch .local_history,目录中的命令会为我提供该目录中执行的所有命令的本地历史文件,而不会丢失主历史文件。我猜类似的东西会在zsh中工作。


0

至少在bash中,仅在shell实例开始时才查询HISTFILE。除非您上面的“ workon”示例创建了一个shell实例,否则按目录的想法将在这里行不通。

也许你可以看一下

alias workon='script ./.history.log'

但是脚本也会创建一个子shell。

简而言之,您可能需要杂乱无章的子外壳级别才能使它工作。


该死的,我希望那会很简单。不管怎么说,还是要谢谢你!
西蒙(Simon)

0

我在生产软件公司工作过,我们只是在为各种功能创建新用户和组。专门用于配置管理或软件构建的新用户帐户,通过组成员身份和ACL 对其他相关功能区域具有不同的可见性级别,并且说的命令历史记录cmmgr将保存在中~cmmgr/.bash_historybldmgr相关字词将保存在中~bldmgr/.bash_history,等等。不幸的是,要登录,用户必须拥有其登录目录。因此,将项目区域完全设置在单独的磁盘上。文件创建者的所有权显示了在项目区域中哪个功能区域创建了文件,.bash_history可以对其进行适当检查。

但是,上述方法并未提供您想要的粒度,但是,它为您提供了一个框架,当与组成员身份结合使用时,用户可以切换组以newgrp有效地创建新的Shell和环境,然后使用一个其他答案中给出的改变帽子的有效~/.bash_history文件的方法之一,以便当一个人通过命令进入和退出新组时,a 可以管理每个文件夹使用和保存的文件。签出。在此问题的其他答案中,沿着这些思路有一些起点。它们应与UNIX组范例一起使用-大多数螺母和螺栓是由shell启动和退出例程处理的,这些例程由cmmgrnewgrp~/.bash_historynewgrpman newgrpnewgrp调用。签出newgrp -l

NAME
     newgrp -- change to a new group

SYNOPSIS
     newgrp [-l] [group]

DESCRIPTION
     The newgrp utility creates a new shell execution environment with modified real and effective group
     IDs.

     The options are as follows:

     -l      Simulate a full login.  The environment and umask are set to what would be expected if the user
             actually logged in again.

0

在这里,我提出了两种变体,但仅适用于Z Shell

变体1

这是我在阅读您的问题标题时首先想到的。使用此变体,您可以使用ALT+ 在两种历史记录模式之间切换h全局本地,后者在chdir时自动切换到每个目录的历史记录。全局历史记录会累积所有已发布的命令。

  • 示范

    〜源src / cd_history
    〜呼应全球历史                                                
    全球历史
    〜mkdir foo酒吧                                                      
    〜[ALT-h]注意本地历史记录的指示器->    +
    〜cd foo +
    〜/ foo在foo中回显本地历史+
    foo的当地历史
    〜/ foo fc -l +
        1在foo中回显本地历史记录
    〜/ foo cd ../bar +
    〜/ bar在bar中回显本地历史+
    酒吧的当地历史
    〜/ bar fc -l +
        1在酒吧回声当地历史
    〜/ bar cd ../foo +
    〜/ foo fc -l +
        1在foo中回显本地历史记录
        3 cd ../bar
    〜/ foo [ALT-h]                                           
    〜/ foo fc -l                                                          
       55源src / cd_history
       64回声全球历史
       65 mkdir foo bar
       66 CD foo
       70在酒吧回响当地历史
       72 CD ../ foo
       73在foo中回应当地历史
       74 cd ../巴
    〜/ foo  
  • 脚本(包含在脚本中~/.zshrc或作为源文件)

    # set options for shared history
    setopt prompt_subst
    setopt share_history
    setopt hist_ignorealldups
    
    # define right prompt as an indicator if local (i.e. per directory) history is enabled
    RPS1=' ${HISTLOC}'
    export HISTLOC=''
    
    # configure global history file and global/local history size
    export HISTGLOBAL=$HOME/.zsh_history
    touch $HISTGLOBAL
    export HISTSIZE=2000
    export SAVEHIST=2000
    
    # define wrapper function and key binding to switch between globel and per-dir history
    function my-local-history()
    {
      if [[ -z $HISTLOC ]]; then
        HISTLOC='+'
        chpwd
      else
        HISTLOC=''
        export HISTFILE=$HISTGLOBAL
        fc -A $HISTFILE
        fc -p $HISTFILE $HISTSIZE $SAVEHIST
      fi
      zle reset-prompt
    }
    zle -N my-local-history
    bindkey "^[h"    my-local-history
    
    # install hook function which is called upon every directory change
    chpwd () {
      if [[ ! -z $HISTLOC ]]; then
        fc -A $HISTGLOBAL $HISTSIZE $SAVEHIST
        export HISTFILE=$PWD/.zsh_history
        fc -p $HISTFILE $HISTSIZE $SAVEHIST
        touch $HISTFILE
      fi 
    }

变体2

再考虑一下,似乎每个目录的历史记录都太细了,您还可以在问题正文中描述每个项目的历史记录。因此,我想出了另一个带有workon函数的变体,可以在项目之间进行切换。每个项目都有自己的历史文件~/.zsh_projhistory_[name]

  • 示范

    〜源src / proj_history 
    〜呼应全球历史                                                                    
    全球历史
    〜[ALT-h]                                                               [使用workon]
    〜workon foo [使用workon]
    〜项目foo中的echo命令[在proj foo上]
    项目foo中的命令
    〜fc -l [关于proj foo]
        项目foo中有1条echo命令
    〜workon bar [在proj foo上]
    〜回显另一个名为bar的项目[proj bar]
    另一个项目,名为bar
    〜fc -l [在项目栏上]
        1回呼另一个项目,名为bar
    〜workon foo [在项目栏上]
    〜fc -l [关于proj foo]
        项目foo中有1条echo命令
        3个工作吧
    〜[ALT-h]                                                              [在proj foo上]
    〜
    〜fc -l                                                                                   
       31回响全球历史
       36呼应另一个项目,名为bar
       38 Workon Foo
       39项目foo中的echo命令
       40个工作吧
    〜ls -1 .zsh_ *
    .zsh_history
    .zsh_projhistory_bar
    .zsh_projhistory_foo
  • 脚本(包含在脚本中~/.zshrc或作为源文件)

    # set options for shared history
    setopt prompt_subst
    setopt share_history
    setopt hist_ignorealldups
    
    # define right prompt as an indicator if local (i.e. per directory) history is enabled
    RPS1=' ${HISTLOC}'
    export HISTLOC=''
    
    # configure global history file and global/local history size
    export HISTGLOBAL=$HOME/.zsh_history
    touch $HISTGLOBAL
    export HISTFILE=$HISTGLOBAL
    export HISTSIZE=2000
    export SAVEHIST=2000
    
    # define wrapper function and key binding to switch between globel and per-dir history
    function my-local-history()
    {
      if [[ -z $HISTLOC ]]; then
        if [[ -z $HISTLOC ]]; then
          HISTLOC='+'
          [[ -z "$HISTPROJ" ]] && HISTLOC='[use workon]' || workon "$HISTPROJ"
        fi
      else
        HISTLOC=''
        export HISTFILE=$HISTGLOBAL
        fc -A $HISTFILE
        fc -p $HISTFILE $HISTSIZE $SAVEHIST
      fi
      zle reset-prompt
    }
    zle -N my-local-history
    bindkey "^[h"    my-local-history
    
    # function to change project
    workon () {
      if [[ -z "$1" ]]; then
        echo Usage: workon [project name]
        return 1
      fi
      export HISTPROJ="$1"
      if [[ ! -z $HISTLOC ]]; then
        fc -A $HISTGLOBAL $HISTSIZE $SAVEHIST
        export HISTFILE=$HOME/.zsh_projhistory_"$HISTPROJ"
        fc -p "$HISTFILE" $HISTSIZE $SAVEHIST
        touch "$HISTFILE"
        HISTLOC="[on proj $HISTPROJ]"
      fi 
    }

0

在一个地区工作了一段时间之后。

历史记录> hist1.txt,然后更新历史记录> hist2.txt

有时我使用日期作为文件名。历史记录> hist20180727.txt

这样,每个目录都有最近的命令历史记录。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.