В вашей команде printf
есть управляющие последовательности, например, printf"\33[2K.....
, (\e[2K
очищает строку), что обязательно является управляющей командой для терминала, которая может быть понята и выполнена только терминальным устройством.
Когда вы выполняете сценарий интерактивно внутри терминала, терминал правильно интерпретирует последовательность. При сохранении вывода команды в файл последовательность воспринимается буквально, так как интерпретировать последовательность нечем.
Теперь, если вы сделаете:
cat test.txt
вы увидите, что терминал снова правильно интерпретирует последовательность перед выводом на печать.
Не вводите команду в командную строку, чтобы запустить ее! Это очень ненадежно — то, что вы пытаетесь сделать, предполагает, что в текущей подсказке еще ничего не набрано. Вместо этого привяжите ключ к команде оболочки, а не к команде линейного редактирования.
В 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
В 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