
(First posting to Pl net Commandline!
Tag: pcli)
Vutral asked in IRC how to synchronise two shells environment
while they re running. As you may know, POSIX systems cannot change
a process environment vector after it has been started, only the
process itself can. Well,
the shell
can, and we ll use a variety of things for this.
This trick assumes you have
$HISTFILE set to the same
pathname in both shells (obviously, they run under the same user).
It uses
export -p to render the current list of exported
variables, then transforms the list from newline-separated to a
single big one-line export statement.
Then it transforms all
remaining newlines (which will be part of a single-quoted string,
since that s
mksh(1) s export format) into the sequence
'$'\n'' which means: terminate current single-quoted
string, append
$'\n' and open up a new single-quoted
string immediately; concatenate these three.
Now,
$'\n'
is just a fancy way of saying newline, and part of mksh because
David Korn (yes, the Korn in Korn Shell) strongly suggested to
me that this functionality be included but, as we can see here,
it pays off.
Finally, the so transformed string is prepended
by
unset \$(export); which, when executed, will cause the
shell to unset (and unexport) all currently exported variables.
The shell parameters that are not exported, i.e. not in the
environment, are not affected by this code (except for
$x
and
$nl, but whatever).
This string is then passed
to
read -s (plus
-r and clearing
IFS to
enable raw mode), which means, read into the parameter
$REPLY
(which we conveniently don t use but it s trashed too, thus) but
store into history at the same time.
Ah hah! Now, the persistent history feature comes into effect!
After running the below statement in the source shell, switch
into the terminal running the destination shell, press Enter
once on the empty line (Ctrl-U to empty it if it wasn t), then
Cursor-Up ( ) to recall voil , an insanely large line with the
previously created string sorta expanded and press Enter again
to run it. Now your set of exported parameters is the exact same
(minus if you exported
IFS,
nl,
x or
REPLY) as in the source shell.
I ve added extra spaces and a linewrap below,
this is really just one big line:
nl=$'\n'; x=$(export -p); x=$ x//$ nl export/ ;
IFS= read -rs <<<"unset \\\$(export);$ x//$nl/\'\$\'\\\\n\'\' "