Getting to grips with history.

I've never really spent much time making use of history, but it's time to try and get familiar with it.

I know I can scroll through my history with the up/down arrow keys, but I'd like to be presented with a scrollable history list from which I could make a selection. I'm sure I have used such a thing but can't remember where.

It looks like the shell you use has quite a bearing on how you handle history. Looking through various guides, it suggests that using '!' with a number will invoke the command corresponding to that position in your history, but that doesn't seem to work with 'sh'. Is there a way to do that in 'sh'?



has some info on history and mentions things like 'fc -e - d' but I don't see any explanation of how this works.

Does anyone know of a guide?
 
Haven't mastered how to recall an entry in sh history yet. But if you bind like this
bind ^R ed-search-prev-history,
you can use Ctrl-R to search in the history. It works like this: type in a few characters of the command you want to search for, then press Ctrl-R.
 
man builtin says:
Commands marked “No**” under External do exist externally, but are implemented as scripts using a builtin command of the same name.
Command External csh(1) sh(1)
history No Yes No

If I do understand this correctly there is no history command for sh, but you can see the passed commands stored in the file .sh_history, so fc can be used, it works for me.
I don't know if it's the answer you look for though.

PS:
sorry the quote messed up the man display.
 
man builtin says:


If I do understand this correctly there is no history command for sh, but you can see the passed commands stored in the file .sh_history, so fc can be used, it works for me.
I don't know if it's the answer you look for though.

PS:
sorry the quote messed up the man display.
history does work under sh, but it is a builtin function. Unfortunately history() doesn't give me anything in the way of options for fc. Running fc on it's own simply shows:

fc: missing history argument
 
Code:
       fc [-e editor] [first [last]]

       fc -l [-nr] [first [last]]

       fc -s [old=new] [first]
           The  fc    built-in command lists,    or edits and re-executes, com-
           mands previously    entered    to an interactive shell.

           -e editor
               Use the editor named by editor to  edit    the  commands.
               The  editor string is a command name, subject to    search
               via the PATH variable.  The value in the     FCEDIT     vari-
               able is used as a default when -e is not    specified.  If
               FCEDIT  is null or unset, the value of the EDITOR vari-
               able is used.  If EDITOR    is null     or  unset,  ed(1)  is
               used as the editor.

           -l (ell)
               List  the  commands  rather  than invoking an editor on
               them.  The commands are written in the  sequence     indi-
               cated  by  the  first and last operands,    as affected by
               -r, with    each command preceded by the command number.

           -n      Suppress    command    numbers    when listing with -l.

           -r      Reverse the order of the    commands listed    (with  -l)  or
               edited (with neither -l nor -s).

           -s      Re-execute the command without invoking an editor.

           first

           last    Select  the  commands  to  list or edit.     The number of
               previous    commands that can be accessed  are  determined
               by  the    value  of the HISTSIZE variable.  The value of
               first or    last or    both are one of    the following:

               [+]num  A positive number representing a     command  num-
                   ber;  command numbers can be displayed with the
                   -l option.

               -num    A negative decimal number representing the com-
                   mand that was executed num of  commands    previ-
                   ously.  For example, -1 is the immediately pre-
                   vious command.

               string  A  string  indicating the most recently entered
                   command that begins with    that string.   If  the
                   old=new    operand    is not also specified with -s,
                   the string form of  the    first  operand    cannot
                   contain an embedded equal sign.

           The following variables affect the execution of fc:

           FCEDIT     Name of the editor to use for history editing.

           HISTSIZE     The number of previous    commands that are accessible.
 
history does work under sh, but it is a builtin function
Turns out history in sh is only an alias ^_^
Code:
root@vm:~ # history -h
fc: Illegal option -h
root@vm:~ #
root@vm:~ # type history
history is an alias for fc -l
root@vm:~ #
root@vm:~ # type fc
fc is a shell builtin
So whether you type history or fc -l you'll end up with the same output.

I usually do "history" which gives a list and when I find the one I want, I do "!eventnumber"

This works for csh and bash but not sh.
Just in case you didn't get it yet, you can reproduce that with fc -s id_of_the_command
The id_of_the_command is obtained by running fc -l
 
I've set up an alias of !!='fc -s' so that '!! 150' will execute line 150 in the history list. That's as close as I can get to the way csh processes history.

One thing I can't work out is how to set HISTSIZE. All my efforts to set it have failed so far, and haven't found an example of setting it.
 
Haven't mastered how to recall an entry in sh history yet. But if you bind like this
bind ^R ed-search-prev-history,
you can use Ctrl-R to search in the history. It works like this: type in a few characters of the command you want to search for, then press Ctrl-R.

I can't get this to work.

How exactly is 'ed-search-prev-history' supposed to work?

I see it mentioned here:-

 
One thing I can't work out is how to set HISTSIZE. All my efforts to set it have failed so far, and haven't found an example of setting it.
In my case the variable HISTSIZE is defined in the file ~/.shrc just like FCEDIT.

Like this for example:
Code:
HISTSIZE=50
export HISTSIZE
FCEDIT=vi
export FCEDIT

Then fc will 'remember' your last 50 commands passed in the terminal.
The trick is when invoked without range like this fc -l, only the last 10 are shown.
So if you want to see more of them you need to specify a range.
The command fc -l 1 20 shows the first 20 commands you typed.

Hope it helps
 
Thanks to gotnull I have a much better understanding of how history can be used, although one thing I would like to have, but not sure if it is possible, is to have a scrollable list of previous commands, similar to that available in Midnight Commander when pressing Alt-h.

Is there any simple way to do this?
 
I don't use Midnight commander but eventually you can add a shell function in your file ~/.shrc to accomplish it.
Code:
hist() {
local t f
t=$(mktemp)
f=$(mktemp)
fc -l 1 50 | tee $t
awk '{print substr($0, index($0, $2))}' $t | tee $f
less $f
rm -f $t $f
}

Do not forget to source your ~/.shrc file after modification: . ~/.shrc
Now when you type hist you'll have your history through the less command, type q key to quit.

Another example, this function reex works interactively and requires textproc/fzy.
It lists all your old commands(50) and then re-execute the one you've selected.
Use arrows to go up or down, or as usual type q to quit.
Code:
reex() {
local sel id
sel=$(fc -l 1 50 | fzy --lines=45)
id=$(echo $sel | awk '{print $1}')
fc -s $id
}


EDIT:
I updated the function hist, I removed the id in front of the line history because it's not needed in this case I guess, only the command is interesting.
It looks a bit better like that.
 
Back
Top