Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Persistent history in python cmd module

Is there any way to configure the CMD module from Python to keep a persistent history even after the interactive shell has been closed?

When I press the up and down keys I would like to access commands that were previously entered into the shell on previous occasions that I ran the python script as well as the ones I have just entered during this session.

If its any help cmd uses set_completer imported from the readline module

like image 562
PJConnol Avatar asked Sep 14 '16 16:09

PJConnol


People also ask

What is CMD module in Python?

The Cmd class provides a simple framework for writing line-oriented command interpreters. These are often useful for test harnesses, administrative tools, and prototypes that will later be wrapped in a more sophisticated interface.

How do I view Python code history?

Enter the python REPL in your terminal by entering python (if you have different path variables for python and python3, you may want to enter python3 ). Write a bit of code and call history(1) to see that the last command — history(1) — is printed to the console.

Where does Python Store history?

The History Log is stored in the . spyder-py3 (Python 3) or spyder (Python 2) directory in your user home folder (by default, C:/Users/username on Windows, /Users/username for macOS, and typically /home/username on GNU/Linux).


1 Answers

readline automatically keeps a history of everything you enter. All you need to add is hooks to load and store that history.

Use readline.read_history_file(filename) to read a history file. Use readline.write_history_file() to tell readline to persist the history so far. You may want to use readline.set_history_length() to keep this file from growing without bound:

import os.path
try:
    import readline
except ImportError:
    readline = None

histfile = os.path.expanduser('~/.someconsole_history')
histfile_size = 1000

class SomeConsole(cmd.Cmd):
    def preloop(self):
        if readline and os.path.exists(histfile):
            readline.read_history_file(histfile)

    def postloop(self):
        if readline:
            readline.set_history_length(histfile_size)
            readline.write_history_file(histfile)

I used the Cmd.preloop() and Cmd.postloop() hooks to trigger loading and saving to the points where the command loop starts and ends.

If you don't have readline installed, you could simulate this still by adding a precmd() method and record the entered commands yourself.

like image 160
Martijn Pieters Avatar answered Sep 23 '22 10:09

Martijn Pieters