Is there a way to modify the command that is about to execute?
I would like to redirect the output to a file, as well as print it on the terminal.
I found that ls > file.txt | cat
does the job, so I would like to add that > file.txt | cat
to any command that is about to execute.
Is there a better way to redirect to file and print to terminal? I am trying to make a logger.
You can change the action that is performed when you execute a line to alter the command that will be executed. This can be done by defining a function which you then bind to the enter key.
Lets first define a function that can add the '> file.txt | cat' ending to any command:
function log_and_accept {
BUFFER="$BUFFER > file.txt | cat"
zle accept-line
}
The next part is to actually replace the default enter key behaviour with your new function. The default behaviour we are replacing is the accept-line function, and if we look at the zle documentation, you will see that accept-line is bound to ^J and ^M.
To bind this function to those letters you first need to turn it into a widget:
zle -N log_and_accept_widget log_and_accept
Then you can bind it, replacing the old behaviour:
bindkey '^J' log_and_accept_widget
bindkey '^M' log_and_accept_widget
Now you will be expanding that command for every single command you do. Every cd, ls, vim etc etc. As such I recommend that you define a couple more functions that actually turn this on and off:
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
I think you should be careful with this. After testing it a little, I quickly grew to dislike it.
There are several ways to do that, the 1 I like the most is this block I found here 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
Also notice that I added 'fc' '> file.txt | cat'
to the list abk
What this does in that that you type fc
after the command and then you hit ,. (comma and period) in rapid succession and zsh will replace fc
for > file.txt | cat
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With