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

В вашей команде printf есть управляющие последовательности, например, printf"\33[2K..... , (\e[2K очищает строку), что обязательно является управляющей командой для терминала, которая может быть понята и выполнена только терминальным устройством.

Когда вы выполняете сценарий интерактивно внутри терминала, терминал правильно интерпретирует последовательность. При сохранении вывода команды в файл последовательность воспринимается буквально, так как интерпретировать последовательность нечем.

Теперь, если вы сделаете:

cat test.txt

вы увидите, что терминал снова правильно интерпретирует последовательность перед выводом на печать.

3
11.06.2017, 00:27
2 ответа

Не вводите команду в командную строку, чтобы запустить ее! Это очень ненадежно — то, что вы пытаетесь сделать, предполагает, что в текущей подсказке еще ничего не набрано. Вместо этого привяжите ключ к команде оболочки, а не к команде линейного редактирования.

В bash используйте bind -x .

bind -x '"\C-xr": . ~/.bashrc'

Если вы также хотите перечитать конфигурацию readline, нет простого способа смешивать команды readline и команды bash в привязке клавиш. Неуклюжий способ — привязать ключ к макросу readline, содержащему две последовательности клавиш: одну — к команде readline, которую вы хотите выполнить, а другую — к команде bash.

bind '"\e[99i~": re-read-init-file'
bind -x '"\e[99b~": . ~/.bashrc'
bind '"\C-xr": "\e[99i~\e[99b~"'

В zsh используйте zle -N , чтобы объявить функцию как виджет, затем bindkey , чтобы привязать этот виджет к клавише.

reread_zshrc () {
  . ~/.zshrc
}
zle -N reread_zshrc
bindkey '^Xr' reread_zshrc
4
27.01.2020, 21:21

В man bashя нашел переменную окружения HISTIGNORE, описание которой выглядит следующим образом:

HISTIGNORE

        A  colon-separated list  of patterns  used to  decide which  command
        lines should be saved on the  history list. Each pattern is anchored
        at the  beginning of the line  and must match the  complete line (no
        implicit `*' is  appended). Each pattern is tested  against the line
        after the checks  specified by HISTCONTROL are  applied. In addition
        to the  normal shell  pattern matching  characters, `&'  matches the
        previous history  line. `&'  may be escaped  using a  backslash; the
        backslash  is removed  before  attempting a  match.  The second  and
        subsequent lines  of a multi-line  compound command are  not tested,
        and are added to the history regardless of the value of HISTIGNORE.

Итак, я экспортировал следующее значение в~/.bashrc:

bind '"\C-xr":   ". ~/.bashrc \C-x\C-z1\C-m"'
bind '"\C-x\C-z1":  re-read-init-file'

export HISTIGNORE="clear:history:. ~/.bashrc "

Последняя строка должна запрещать bashсохранять любую команду clear, historyи, что более важно, . ~/.bashrc.


Для zshя нашел вариант HIST_IGNORE_SPACE, который описан вman zshoptions:

HIST_IGNORE_SPACE (-g)

        Remove command lines  from the history list when the  first character on
        the line  is a  space, or when  one of the  expanded aliases  contains a
        leading space. Only  normal aliases (not global or  suffix aliases) have
        this behaviour.  Note that the  command lingers in the  internal history
        until the  next command is entered  before it vanishes, allowing  you to
        briefly reuse or edit the line. If you want to make it vanish right away
        without entering another command, type a space and press return.

Согласно тому, что там написано, если эта опция включена, zshдолжен удалить из истории все команды, начинающиеся с пробела. Однако он временно остается во внутренней истории, пока не будет выполнена следующая команда. Итак, я установил эту опцию в ~/.zshrc, а затем переопределил привязку клавиш к -источнику конфигурации оболочки следующим образом:

    setopt HIST_IGNORE_SPACE
    bindkey -s '^Xr' '. ~/.zshrc^M ^M'
#                     │            │
#                     │            └─ command containing only a space to force `zsh`
#                     │               to “forget“ the previous command immediately
#                     └─ space added to prevent `zsh` from logging the command
0
27.01.2020, 21:21

Теги

Похожие вопросы