Файлы журналов bash / zsh для отдельных каталогов


12

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

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

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

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

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

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

Ответы:


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

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

Для 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Думаю, вам придется переопределить переменную. Но это выглядело бы похоже.

Чао!


2

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

Монтаж

pip install virtualenvwrapper

или же

easy_install virtualenvwrapper

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


1

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


Спасибо - я посмотрю на это. Может сделать что-то близкое к тому, что мне нужно!
Симон

1

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

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

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


1

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

#!/bin/cat
some
relevant
commands

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

.howto.datadump
.howto.restart

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


В качестве альтернативы вы можете использовать README.mdили создавать другие .mdфайлы для каждой темы и указывать на них в файле readme. Это если у вас есть дружественный к уценке интерфейс управления исходным кодом.
Рено

0

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

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

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

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

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


Черт, я надеялся, что это будет что-то простое. Спасибо, в любом случае!
Симон

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 . Глобальная история накапливает все выданные команды.

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

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

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

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

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

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

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

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.