Skip to content

Instantly share code, notes, and snippets.

@kenichi
Last active August 27, 2020 23:01
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
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