⚠ This page contains old, outdated, obsolete, … historic or WIP content! No warranties e.g. for correctness!
All 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
(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:
Of course, this makes a nice function, for your ~/.mkshrc or somesuch.