15

Since upgrading to Python 3.4, all interactive commands are logged to ~/.python_history. I don't want Python to create or write to this file.

Creating a symlink to /dev/null does not work, Python removes the file and recreates it. The documentation suggests to delete the sys.__interactivehook__, but this also removes tab-completion. What should be done to disable writing this history file but still preserve tab-completion?

Additional details:

10
  • Have you tried chowning it to root? Commented Mar 25, 2014 at 15:45
  • @goldilocks I do not consider that an acceptable solution, and neither is using chattr. I am looking for a single (user) configuration file or environment variable. Commented Mar 25, 2014 at 15:47
  • Okay, but you already know there is no such acceptable solution since you've looked at the documentation. Commented Mar 25, 2014 at 15:50
  • In fact, chmod is the solution suggested by python devs in this bug report from a few weeks ago, although there is also some mention of ~/.inputrc there (there is no man readline, BTW, except for the library function). Commented Mar 25, 2014 at 15:55
  • @goldilocks Yes, I was about to link to that bug report. I don't know how to use inputrc though and chmod does not work for me either, the file gets modified anyway (Arch Linux). There exists an info inputrc page, but I am generally not so happy with reading info pages as they are difficult to navigate through. Commented Mar 25, 2014 at 15:56

9 Answers 9

14

Another ~/.pythonrc solution:

import readline
readline.write_history_file = lambda *args: None
3
  • I don't know why this isn't upvoted more. This is simple and directly suppresses writing the history file instead of disabling history entirely. Commented Sep 4, 2019 at 19:53
  • This was the only fix that worked for me. Thanks. Commented Dec 8, 2019 at 21:10
  • So I get to replace one turd in my home directory with another Commented Sep 23, 2022 at 23:11
9

As of Python 3.6, you can use readline.set_auto_history to disable this:

import readline
readline.set_auto_history(False)
5
  • That's good for the Python shell, but beware: it doesn't seem to work in ipython. Commented Sep 2, 2019 at 8:58
  • This disables history entirely. Personally I'm fine with history being preserved in my interpreter session, but I just don't want my history written to disk and preserved across sessions. Commented Sep 4, 2019 at 18:28
  • 3
    Doesn't work. This doesn't stop the file being saved, and instead it breaks the history during the session. In any case, Python silently turns the "feature" back on next time you run it. Commented Dec 8, 2019 at 20:51
  • This works for me, and can be applied to every session with an alias. For example: alias python='python -i -c "import readline; readline.set_auto_history(False)". Commented Mar 6, 2022 at 19:00
  • For those saying this doesn't work, it's supposed to be added to ~/.pythonrc so it runs before every session. Commented Jun 1, 2022 at 9:48
6

This works for me.

Creating ~/.pythonrc file:

import os
import atexit
import readline

readline_history_file = os.path.join(os.path.expanduser('~'), '.python_history')
try:
    readline.read_history_file(readline_history_file)
except IOError:
    pass

readline.set_history_length(0)
atexit.register(readline.write_history_file, readline_history_file)

Then export it:

export PYTHONSTARTUP=~/.pythonrc
4
  • This seems to enable writing a history file instead of disabling it if I am not mistaken? Unless set_history_length does something magical? Tab-completion is done for functions, not history. Commented Mar 25, 2014 at 16:52
  • @Lekensteyn: yes, it make history size equal zero so nothing is written to history file. Oh, I though you want to preserve command between sessions. Commented Mar 25, 2014 at 16:54
  • 2
    This still causes ~/.python_history to be written (verified with PYTHONSTARTUP=$HOME/.pythonrc strace -e file,write -o /tmp/st python). I start to think that there is no way to disable this, but keep tab-completion without duplicating code from /usr/lib/python3.4/site.py. Commented Mar 25, 2014 at 16:58
  • AFAIK, there is no way to really disable it. Commented Mar 25, 2014 at 17:06
2

To prevent Python from writing ~/.python_history, disable the hook that activates this functionality:

import sys
# Disable history (...but also auto-completion :/ )
if hasattr(sys, '__interactivehook__'):
    del sys.__interactivehook__

If you would like to enable tab-completion and disable the history feature, you can adapt the site.enablerlcompleter code. Write the following code to ~/.pythonrc and set export PYTHONSTARTUP=~/.pythonrc in your shell to enable it.

import sys
def register_readline_completion():
    # rlcompleter must be loaded for Python-specific completion
    try: import readline, rlcompleter
    except ImportError: return
    # Enable tab-completion
    readline_doc = getattr(readline, '__doc__', '')
    if readline_doc is not None and 'libedit' in readline_doc:
        readline.parse_and_bind('bind ^I rl_complete')
    else:
        readline.parse_and_bind('tab: complete')
sys.__interactivehook__ = register_readline_completion
3
  • This does the job. I wonder why they're not using ${XDG_STATE_HOME}/python/history for this purpose, though. Commented Sep 27, 2021 at 1:02
  • Any idea where the history filename path (~/.python_history) is stored? Commented Jan 24, 2022 at 1:12
  • 1
    See the site.enablerlcompleter link in my answer. It is hard-coded there. On Python 3.10.2 on Arch Linux, it can be found on line 475 of /usr/lib/python3.10/site.py. Commented Feb 1, 2022 at 22:28
2

My current solution (for recent enough versions of Python 3) prevents default use of ~/.python_history but leaves the possibility of explicit writing of the history to a given file (using readline.write_history_file(filename) or readline.append_history_file(...)) is to have the following in one's PYTHONSTARTUP file:

import readline
import time

readline.add_history("# " + time.asctime()) # prevent default use of ~/.python_history
readline.set_history_length(-1) # unlimited

It has the pleasant (for me) side effect labeling any explicitly written history with the startup time of the interpreter. It works because of the fix for bug 5845 which can be seen here.

1
  • History length of -1 (i.e. unlimited) is already the default (verify with readline.get_history_length()), so that line is optional. Commented Jun 1, 2022 at 12:23
1

Until it's fixed in some way in Python itself you can do this on UNIX systems:

rm ~/.python-history
mkdir ~/.python-history
sudo chattr +i ~/.python-history || sudo chflags simmutable ~/.python-history

After that you will be getting

Error in atexit._run_exitfuncs:

IsADirectoryError: [Errno 21] Is a directory

every time you terminate a python shell. Exit status will still be 0.

Notice that if you leave it as file you need to create and make immutable another file, ~/.python_history

0

Put the following in a file and set PYTHONSTARTUP to it (or call the file sitecustomize.py and make it accessible from the PYTHONPATH)

import readline
import atexit
import sys

sys.__interactivehook__()
atexit.unregister(readline.write_history_file)

This way you'll still have access to tab-completion and previous history, but the commands you enter won't be added to the history file.

2
  • This does not seem to work (Python 3.5.1 on Arch Linux), the history file is still written on exit even through the PYTHONSTARTUP script is indeed executed. Commented Feb 9, 2016 at 14:39
  • I just tested it on my Arch Linux vm, and it works fine: gist.github.com/berdario/640b3ab00b128fdf3338 Commented Feb 10, 2016 at 0:54
0

Here's my method (which turned out to be basically a more reliable and pythonic version of berdario's method). It only disables writing to .python_history, but not reading from it if it exists, or appending new lines to the current instance's history. I recommend saving it as site-packages/sitecustomize.py, because site is the module that both writes to .python_history and imports sitecustomize if it exists, although naming it something else and pointing to it with PYTHONSTARTUP works too.

import sys
oldhook = getattr(sys, '__interactivehook__', None)
if oldhook:
    def newhook():
        import readline, atexit
        oldhook()
        atexit.unregister(readline.write_history_file)
    sys.__interactivehook__ = newhook

update: what i did for 3.7, specific to my system, not pep8:

import rlcompleter,readline as r,sys
def f():r.parse_and_bind('tab:complete');r.read_init_file()
sys.__interactivehook__=f
1
  • Python 3.7.3. Not working. History still logged. Commented Dec 8, 2019 at 21:06
0

unlink ~/.python_history

ncat -l -U ~/.python_history

(ctrl+c)

chmod 0 ~/.python_history

原理就是生成一个占位的socket file

fifo file也可以 但fifo file对端可以读取 有隐私安全问题

用socket file的话 ncat退出后(没有新的进程删除并监听这个文件)对端是断的

另外 mknod ~/.python_history c 1 3 也可以

原理是生成 /dev/null 类似的文件

但是需要 root 权限

另外mkdir ~/.python_history也可以

但是python退出时有丑陋的报错

1
  • 1
    As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center. Commented Jun 19 at 7:49

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.