Skip to content

Instantly share code, notes, and snippets.

@kenichi
Last active August 27, 2020 23:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kenichi/e7f785578f603715cec7b5fa217673c9 to your computer and use it in GitHub Desktop.
Save kenichi/e7f785578f603715cec7b5fa217673c9 to your computer and use it in GitHub Desktop.

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