Модификация команды zsh preexec
Есть ли способ изменить команду, которая собирается выполнить? Я хотел бы перенаправить вывод в файл, а также распечатать его на терминале. я нашел это ls > file.txt | cat
делает работу, поэтому я хотел бы добавить, что > file.txt | cat
к любой команде, которая собирается выполнить.
Есть ли лучший способ перенаправить в файл и распечатать на терминал? Я пытаюсь сделать регистратор.
2 ответа
Вы можете изменить действие, которое выполняется при выполнении строки, чтобы изменить команду, которая будет выполняться. Это можно сделать, определив функцию, которую вы затем привязываете к клавише ввода.
Давайте сначала определим функцию, которая может добавить '> file.txt | кошка, заканчивающаяся любой командой:
function log_and_accept {
BUFFER="$BUFFER > file.txt | cat"
zle accept-line
}
Следующая часть заключается в том, чтобы фактически заменить поведение клавиши ввода по умолчанию новой функцией. Поведение по умолчанию, которое мы заменяем, - это функция accept-line, и если мы посмотрим на документацию zle, вы увидите, что accept-line связана с ^J и ^M.
Чтобы связать эту функцию с этими буквами, сначала нужно превратить ее в виджет:
zle -N log_and_accept_widget log_and_accept
Затем вы можете связать его, заменив старое поведение:
bindkey '^J' log_and_accept_widget
bindkey '^M' log_and_accept_widget
Теперь вы будете расширять эту команду для каждой команды, которую вы делаете. Каждый cd, ls, vim и т. Д. И т. Д. Поэтому я рекомендую вам определить еще пару функций, которые фактически включают и выключают это:
function turn_on_logging {
bindkey '^J' log_and_accept_widget
bindkey '^M' log_and_accept_widget
}
function turn_off_logging {
bindkey '^J' accept-line
bindkey '^M' accept-line
}
zle -N turn_on_logging_widget turn_on_logging
zle -N turn_off_logging_widget turn_off_logging
bindkey '^P' turn_on_logging_widget
bindkey '^O' turn_off_logging_widget
Я думаю, вы должны быть осторожны с этим. После небольшого тестирования я быстро полюбил это.
Есть несколько способов сделать это, 1 мне больше всего нравится этот блок, который я нашел здесь http://git.grml.org/?p=grml-etc-core.git;a=blob_plain;f=etc/zsh/zshrc;hb=HEAD
abk=(
'...' '../..'
'....' '../../..'
'BG' '& exit'
'C' '| wc -l'
'G' '|& grep '${grep_options:+"${grep_options[*]}"}
'H' '| head'
'Hl' ' --help |& less -r' #d (Display help in pager)
'L' '| less'
'LL' '|& less -r'
'M' '| most'
'N' '&>/dev/null' #d (No Output)
'R' '| tr A-z N-za-m' #d (ROT13)
'SL' '| sort | less'
'S' '| sort -u'
'T' '| tail'
'V' '|& vim -'
'co' './configure && make && sudo make install'
'fc' '> file.txt | cat'
)
zleiab() {
emulate -L zsh
setopt extendedglob
local MATCH
if (( NOABBREVIATION > 0 )) ; then
LBUFFER="${LBUFFER},."
return 0
fi
matched_chars='[.-|_a-zA-Z0-9]#'
LBUFFER=${LBUFFER%%(#m)[.-|_a-zA-Z0-9]#}
LBUFFER+=${abk[$MATCH]:-$MATCH}
}
zle -N zleiab && bindkey ",." zleiab
Также обратите внимание, что я добавил 'fc' '> file.txt | cat'
к списку abk
Что это делает в том, что вы печатаете fc
после команды, а затем вы нажмете . (запятая и точка) в быстрой последовательности и Zsh заменит fc
за > file.txt | cat