Модификация команды 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

Другие вопросы по тегам