Skip to content

Instantly share code, notes, and snippets.

@kenichi
Last active Aug 27, 2020
Embed
What would you like to do?

why can't it write to the history file and why is the error opaque?

first, let's see the UID python runs as:

% docker run --rm -it -v ~/.inputrc:/root/.inputrc:ro -v ~/.python_history:/root/.python_history:rw python:3.7 python -c 'import os; print(os.getuid())'   
0
%

ok, 0 aka root - as expected. now let's see who owns the file and its permissions:

% docker run --rm -it -v ~/.inputrc:/root/.inputrc:ro -v ~/.python_history:/root/.python_history:rw python:3.7 ls -aln /root/.python_history
-rw------- 1 0 0 584 Aug 26 16:16 /root/.python_history
%

alright, 0 aka root - as expected, and 0600 - also as expected. so... why can't python write history to the file at exit??

% docker run --rm -it -v ~/.inputrc:/root/.inputrc:ro -v ~/.python_history:/root/.python_history:rw python:3.7 python -i
Python 3.7.7 (default, May 16 2020, 07:16:36) 
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> print("hi")
hi
>>> 
Error in atexit._run_exitfuncs:
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site.py", line 445, in write_history
    readline.write_history_file(history)
OSError: [Errno -1] Unknown error -1
%

note that it can write it fine, when the file is not bind mounted in:

 % docker run --rm -it -v ~/.inputrc:/root/.inputrc:ro python:3.7 python -i
Python 3.7.7 (default, May 16 2020, 07:16:36) 
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> print("hi")
hi
>>>
%

i just want repl history in ephemeral containers is that so hard 😭

here is python's native code to call readline's write_history(): https://github.com/python/cpython/blob/3.7/Modules/readline.c#L245

let's find the readline version...

% docker run --rm -it -v ~/.inputrc:/root/.inputrc:ro python:3.7 dpkg-query -l 'libreadline*'
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name                  Version      Architecture Description
+++-=====================-============-============-============================
==========================
un  libreadline-common    <none>       <none>       (no description available)
ii  libreadline-dev:amd64 7.0-5        amd64        GNU readline and history lib
raries, development files
un  libreadline-gplv2-dev <none>       <none>       (no description available)
un  libreadline4          <none>       <none>       (no description available)
un  libreadline5          <none>       <none>       (no description available)
un  libreadline5-dev      <none>       <none>       (no description available)
un  libreadline6-dev      <none>       <none>       (no description available)
ii  libreadline7:amd64    7.0-5        amd64        GNU readline and history lib
raries, run-time libraries

ok, 7.0 and so here is readline's write_history(): https://git.savannah.gnu.org/cgit/readline.git/tree/histfile.c?h=readline-7.0#n783

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment