Помните «локальную» историю Bash в папке?

11

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

Фабер
источник
3
Интересный вопрос. Кстати, вместо того, чтобы возвращаться «через всю историю», вы можете использовать Ctrl + R для ее поиска, это то, что я бы сделал в таких ситуациях.
августа
да, это помогает, но в этом случае у меня есть только последний. Есть ли возможность получить более одного результата?
Фабер
1
Вы можете продолжать нажимать Ctrl + R после ввода части имени команды.
mtahmed
history | lessвозможно? Это на самом деле не отвечает на ваш вопрос, но именно с этого я и начну.
Ройма
@roaima И затем поиск, используя "/" + search-term + enter, а затем "n" / "N" для дальнейшего поиска вперед / назад.
phk

Ответы:

2

Подключив bash к PROMPT_COMMAND, эта функция запускается каждый раз, когда вы получаете новое приглашение, поэтому самое время проверить, находитесь ли вы в каталоге, для которого вы хотите создать собственную историю. Функция имеет четыре основные ветви:

  1. Если текущий каталог ( $PWD) не изменился, то ничего не делать (возврат).

Если PWD был изменен, то мы создали локальную функцию, единственной целью которой является фактора «пользовательского каталога» код в одном месте. Вы захотите заменить мои тестовые каталоги на свои (разделенные |).

  1. Если мы не перешли в пользовательский каталог или из него, просто обновите переменную «предыдущий каталог» и вернитесь из функции.

Поскольку мы изменили каталоги, обновите переменную «предыдущий каталог», затем сохраните историю в памяти в HISTFILE, а затем очистите историю в памяти.

  1. Если мы перешли в пользовательский каталог, то установите HISTFILE в качестве .bash_historyфайла в текущем каталоге.

  2. В противном случае мы перешли из пользовательского каталога, поэтому верните HISTFILE в исходный каталог.

Наконец, поскольку мы изменили файлы истории, прочитайте их в предыдущей истории.

Чтобы все пошло как надо, скрипт устанавливает значение PROMPT_COMMAND и сохраняет две переменные внутреннего использования (фондовый HISTFILE и «предыдущий каталог»).

prompt_command() {
  # if PWD has not changed, just return
  [[ $PWD == $_cust_hist_opwd ]] && return

  function iscustom {
    # returns 'true' if the passed argument is a custom-history directory
    case "$1" in
      ( */tmp/faber/somedir | */tmp/faber/someotherdir ) return 0;;
      ( * ) return 1;;
    esac
  }

  # PWD changed, but it's not to or from a custom-history directory,
  # so update opwd and return
  if ! iscustom "$PWD" && ! iscustom "$_cust_hist_opwd"
  then
    _cust_hist_opwd=$PWD
    return
  fi

  # we've changed directories to and/or from a custom-history directory

  # save the new PWD
  _cust_hist_opwd=$PWD

  # save and then clear the old history
  history -a
  history -c

  # if we've changed into or out of a custom directory, set or reset HISTFILE appropriately
  if iscustom "$PWD"
  then
    HISTFILE=$PWD/.bash_history
  else
    HISTFILE=$_cust_hist_stock_histfile
  fi

  # pull back in the previous history
  history -r
}

PROMPT_COMMAND='prompt_command'
_cust_hist_stock_histfile=$HISTFILE
_cust_hist_opwd=$PWD
Джефф Шаллер
источник
0

Ответ Джеффа хорош, если вам нужна история для одного каталога, но если вы согласны с установкой zsh, вы можете использовать per-history-directory для получения истории, специфичной для каталога для всех каталогов.

Вы можете установить zsh:

brew install zsh

В качестве альтернативы, если вы хотите установить oh-my-zsh , вы можете добавить плагин histdb и написать собственный запрос, чтобы запросить базу данных sqlite, в которую добавлен histdb. Я написал об этом и добавил автозаполнения в посте Dev Diaries . Проверьте раздел бонусных команд .

Запрос выглядит так

show_local_history() {
    limit="${1:-10}"
    local query="
        select history.start_time, commands.argv 
        from history left join commands on history.command_id = commands.rowid
        left join places on history.place_id = places.rowid
        where places.dir LIKE '$(sql_escape $PWD)%'
        order by history.start_time desc
        limit $limit
    "
    results=$(_histdb_query "$query")
    echo "$results"
}

Это также принимает необязательный лимит:

show_local_history 50

например.

Халик Гант
источник
-1

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

andreatsh
источник
1
Это хороший намек, но не то, что искал ОП. ОП был довольно конкретным для того, что он / она искал (решение я бы тоже подписал, кстати).
phk
@phk Ты прав, в следующий раз я буду более осторожен! Спасибо за ваше объяснение!
andreatsh