11

Я обнаружил, что много работаю над проектом в заданном каталоге. Иногда - несколько месяцев спустя - мне нужно что-то переделать в этом проекте, но я не могу вспомнить, что я сделал. Я использую Mercurial или Git для отслеживания изменений в файлах, но я хочу иметь возможность помнить, какие команды я выполнил в этом каталоге.

Поиск по истории моей оболочки не очень информативен. Я уже записываю все в свои файлы истории. * _, Но мне нужен список того, что я делал в ~/foo/bar, а не всех других (миллионов) вещей, которые я делал на этой неделе. Я, наверное, даже не помню, в каком месяце я последний раз работал над этим конкретным проектом.

Кто-нибудь имеет какие-либо идеи, как файл журнала каталога проекта всех команд оболочки, которые я использовал? Я представляю команду что-то вроде:

работа над моим проектом

... для установки файла журнала оболочки ~/myproject/.history.log, загрузки предыдущей истории из этого файла журнала и, возможно, обновления моего приглашения, чтобы сообщить мне, над каким каталогом я работаю (например, vcprompt для предоставления версии). контрольная информация).

Есть ли что-нибудь подобное?

10 ответов10

3

Мне это тоже нужно, и у меня есть версия, в которой используется переменная Bash PROMPT_COMMAND:

Значение переменной PROMPT_COMMAND проверяется непосредственно перед тем, как Bash напечатает каждое первичное приглашение. Если PROMPT_COMMAND установлен и имеет ненулевое значение, то значение выполняется так же, как если бы оно было введено в командной строке.

Поэтому я говорю PROMPT_COMMAND = "check_for_local_history" в ~/.bashrc.my, где check_for_local_history - моя функция, которая проверяет, была ли последняя выполненная команда изменением каталога, и когда это правда, она проверяет новый текущий каталог для .bash_history файл. Если он есть, используйте его как файл истории.

Вот полная суть: https://gist.github.com/gurdiga/dac8d2e7eb3056d6b839

2

Если вы еще не поняли это: то, что вы ищете, это отличный пакет virtualenvwrapper . Это обертка вокруг python virtualenv (рисунок), и хотя на него часто ссылаются, когда речь идет о среде python, на самом деле это очень общий инструмент, который удовлетворяет вашему варианту использования.

Монтаж

pip install virtualenvwrapper

или же

easy_install virtualenvwrapper

и добавьте материал инициализации в конфигурацию вашей оболочки (~/.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 будет каждый раз расширяться до другого проекта.

2

Один трюк, который я использую для создания субпакетов для продукта, - это использование суб-оболочки.

Для bash вы можете создать скрипт оболочки следующим образом:

#!/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 , что может быть удобно.

Я не уверен, как сделать то же самое в zsh . Я думаю, вам придется переопределить переменную ZDOTDIR . Но это выглядело бы похоже.

Чао!

1

Возможно, вас заинтересует плагин, который я написал, под названием directory-history для zsh.
Смотрите здесь: https://github.com/tymm/directory-history

Хотя он не очень подходит для вашего рабочего процесса в myproject , он должен идеально соответствовать вашим потребностям.

Это создает историю, которая включает в себя каталоги.
Когда вы просматриваете свою историю, вы сначала получите команды из каталога, в котором вы находитесь.
Если для этого каталога не осталось команд, он вернется к глобальной истории и предложит команды, используемые в других каталогах.

1

Если вы хотите что-то простое, у вас может быть файл .history.log как таковой:

#!/bin/cat
some
relevant
commands

Затем запустить файл будет cat тех команд , которые перечислены в ней.
Вы также можете сгруппировать эти команды в отдельные файлы по функциональности в соответствии с соглашением:

.howto.datadump
.howto.restart

Это имеет дополнительное преимущество: работать "из коробки" и не загрязнять окружающую среду.

1

Взгляните на мои сценарии регистрации здесь. Используя один из них, вы можете отслеживать, в каком каталоге вы находитесь, когда вы вводите каждую команду. Вы можете grep файл журнала для команды или другой информации. Я использую длинную версию дома и на работе.

0

По крайней мере, в bash HISTFILE используется только при запуске экземпляра оболочки. Идея per-dir здесь не сработает, если в приведенном выше примере 'workon' не создан экземпляр оболочки.

Может быть, вы можете посмотреть на что-то вроде

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

Но скрипт также создает подоболочку.

Короче говоря, вам, вероятно, понадобятся грязные уровни подоболочек, чтобы это работало.

0

После работы в одной области некоторое время.

history> hist1.txt, затем более поздняя история> hist2.txt

Иногда я использую дату для имени файла. история> hist20180727.txt

Таким образом, существует недавняя история команд для каждого каталога.

0

Я работал в производственных домах программного обеспечения, где мы просто создавали новых пользователей и группы для различных функций. Новые учетные записи пользователей, предназначенные специально для управления конфигурациями или сборками программного обеспечения, с различными уровнями видимости в другие связанные функциональные области через членство в группах и ACL, а также историю команд, выполняемую, скажем, cmmgr , будет сохранена в ~cmmgr/.bash_history , слово, связанное с bldmgr , будет сохранено в ~bldmgr/.bash_history и т. д. К сожалению, для входа в систему пользователь должен иметь свой каталог для входа. Поэтому область проекта была настроена на отдельном диске. Владение создателя файла показало, какая функциональная область создала файлы в области проекта, для чего можно проверить соответствующий .bash_history .

Вышеупомянутый подход, однако, не дает вам желаемой степени детализации, однако он дает вам скелет, который в сочетании с членством в группе, пользователь может переключать группы с помощью newgrp который эффективно создает новую оболочку и среду, а затем использовать один из подходов, приведенных в других ответах, - изменить действующий файл ~/.bash_history при переключении шляп, скажем, cmmgr чтобы newgrp мог управлять тем, какой ~/.bash_history используется и сохраняется для каждой папки при входе и выходе из новой группы. с помощью команды newgrp . Проверьте man newgrp . Есть некоторые отправные точки по этим направлениям в других ответах на этот вопрос. Они должны работать с парадигмой группы UNIX - большинство болтов и гаек обрабатываются процедурами запуска и выхода из оболочки, как это контролируется вызовом newgrp . Проверьте 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. Глобальная история накапливает все выданные команды.

  • демонстрация

    ~ source src/cd_history ~ echo глобальная история глобальная история ~ mkdir foo bar ~ [ALT-h] ~ обратите внимание на индикатор локальной истории -> +~ cd foo +~/foo echo локальная история в foo +локальная история в foo ~/foo fc -l +1 отображает локальную историю в foo ~/foo cd ../bar +~/bar отображает локальную историю в bar +локальную историю в баре ~/bar fc -l +1 отображает локальную историю в bar ~/bar cd ../foo +~/foo fc -l +1 отображает локальную историю в foo 3 cd ../bar ~/foo [ALT-h] ~/foo fc -l 55 source src/cd_history 64 отображает глобальную историю 65 mkdir foo bar 66 cd foo 70 отображает локальную историю в bar 72 cd ../foo 73 отображает локальную историю в foo 74 cd ../bar ~/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

Подумав еще раз, кажется, что история per-dir слишком мелкозернистая, и вы также описываете историю каждого проекта в своем теле вопроса. Поэтому я предложил другой вариант с рабочей функцией для переключения между проектами. Каждый проект имеет свой собственный файл истории ~/.zsh_projhistory_[name] .

  • демонстрация

    ~ source src/proj_history ~ echo глобальная история глобальная история ~ [ALT-h] [использовать workon] ~ workon foo [использовать workon] ~ команда echo в проекте foo [на proj foo] команда в проекте foo ~ fc -l [on proj foo] 1 команда echo в проекте foo ~ workon bar [on proj foo] ~ echo другой proj, названный bar [on proj bar] другой proj, названный bar ~ fc -l [on proj bar] 1 echo другой proj, названный bar ~ workon foo [в proj bar] ~ fc -l [on proj foo] 1 команда эха в проекте foo 3 workon bar ~ [ALT-h] [в proj foo] ~ ~ fc -l 31 отображает глобальную историю 36 отображает другой проект, именованная строка 38 workon foo 39 echo команда в проекте foo 40 workon bar ~ 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 
    }
    

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .