Given a zsh instance that have an entry my_private_dir
in it's named directory table and the zsh instance is used to launch a Python script. How could Python read the value of my_private_dir
?
For example
$ hash -d my_private_dir=/media/user/encrypted_dir
$ hash -d | grep my_private_dir | sed 's/.*=//'
/media/user/encrypted_dir
$ python
>>> get_zsh_named_dir('my_private_dir') # How could python read it?
I've tried system.os
. But it doesn't work, which is expected as it launches a new instance of the shell. Which is a new process and may not have the same named directory table.
# Continuing from the previous code snippet
>>> import os
>>> os.system("echo $SHELL")
/bin/zsh
0
>>> os.system("hash -d | grep my_private_dir | sed 's/.*=//'")
0
So, how could Python read data from the parent zsh's hash table?
Broadly speaking, nothing from your shell is exposed to processes running in it unless exposed specifically, such as via an environment variable. So all you need to do is find a way to expose that table to Python.
You can do this by reading the data into Python as a script, and running Python with -i
to make it become interactive afterwards.
To feed input to a script while still allowing Python to become interactive, the input can't be given as stdin. But luckily, zsh (and bash) have a way to redirect command output as if it were a file, and Python has an easy way to read input from files.
Here's the script: it reads equals-separated key/value pairs from files and/or standard input into a dictionary named eqdict
.
"""eqdict.py
Translate equals-separated key/value lines into a Python dict.
"""
try:
import fileinput
eqdict = {}
for line in fileinput.input():
key, val = line.rstrip().split('=', 1)
eqdict[key] = val
finally:
# Don't pollute the global namespace
del fileinput, line, key, val
And this is how you can use it:
zsh% hash -d some_name=./some_dir/
zsh% python3 -i eqdict.py <(hash -d)
>>> eqdict['some_name']
'./some_dir/'