How to Export Command History into a Shell Script

command historyshellzsh

Often I have complicated installation procedures to follow,
like having to build dependencies for buildtools, to build dependencies for the application I wish to install from source.

Once I have done this once, I don't really want to do have to try and remember all the steps I have done.

The command-history in zsh (and other shells) already records what I have done.
Is it possible to export the last 100 (for example) commands executed in to a .sh script?

I could then edit this script, remove commands that are from before I started installing,
and remove commands that were me making mistake,
and be left with a install script I can give to someone else in a similar environment.
(Or use myself on another machine.).

I suspect, that my command history is already stored in one of the dot-files in my home directory.

Best Answer

The fc built-in command allows you to extract commands from the history using a number of criteria (see man zshbuiltins for details).

fc stands for “fix command”, and when invoked with no parameters it opens an editor with the last command entered. You can use all your editor’s features to change the command, and when you save and exit zsh runs the fixed command. The editor used by default is vi, but that can be overridden using the EDITOR shell variable or, if you want to use a specific editor with the fc command, FCEDIT.

fc has many options to manipulate history beyond the last command, some of which provide exactly the capabilities you're asking for.

The -l option “lists” the contents of the history. By default it lists the last 16 commands, but you can specify lower and upper boundaries, as indices in the history or even as the starting text of a command. Negative indices work back from the last command, so to extract the last 15 lines:

fc -l -15

By default fc -l includes history indices as the first column of its output. Once you have the exact range you want, -n drops the numbers so:

fc -ln -12 -5

will extract only those lines (from 12 back to 5 back) in a format suitable for a script.

Using commands as boundaries can be very useful:

fc -l rm ls

lists all the history starting with the last rm and ending with the last ls (so there will be a single rm command in the output but there may be multiple ls commands).

There are many other options, such as adding timestamps, replacing portions of commands, loading and saving portions of history, switching entire history stacks...

Related Question