bashemacsshcommand-history

How to view the output of history from a non-interactive shell given path to HISTFILE?


In emacs I would like to use shell-command-to-string to essentially retrieve something like history | tail -n5. Issue is that history is a bash built in (in interactive mode only?) so that does not work. As I am merely interested in a read-only snap of the decorated output, is there a way to parse the content of the history file (suppose it is ~/.bash_history) and output it with the line number and date as the history bash command does it?

In other words, is there a way to do something like:

(shell-command-to-string "history --pretty-dump-to-stdout-with-date-time-linenum --filename ~/.bash_history")

? (Or, perhaps, a different workaround?)


Solution

  • Make history command output something

    I expect set -o history to fail as it will use the history file $HISTFILE which most likely is unset for non-interactive shells. Assuming the history is stored in ~/.bash_history you could execute ...

    HISTFILE=~/.bash_history; set -o history; history | tail -n5
    

    However, this would modify your history by adding history | tail -n5. A better approach is to read the history file without enabling the history:

    history -r ~/.bash_history; history | tail -n5
    

    Commands from your current session

    Assume you are inside a interactive terminal session and execute ...

    $ myCommand
    $ emacs # and inside emacs the shell command `history` as shown above
    

    ... then you most likely won't see myCommand in the history. This is because bash only writes the history to your history file when closing the session. You can manually update the history file using history -a, thus the following should work:

    $ myCommand
    $ history -a
    $ emacs # and inside emacs the shell command `history` as shown above
    

    Since most people usually would forget the history -a it would be best to automate this step in your .bashrc, either at each prompt (PROMPT_COMMAND="history -a), or only for emacs (emacs() { history -a; command emacs "$@"; }).

    Pretty Printing

    is there a way to do something like [...] --pretty-dump-to-stdout-with-date-time-linenum

    The history format of the history command is controlled by HISTTIMEFORMAT. The format has to be set and exported before calling history inside emacs.