The Unix shell initialization problem and how shells should work

June 19, 2011

In general, there are at least three sorts of things that you may want to do when a shell is started: one time environment initializations that can be inherited in subshells, per shell things that cannot be inherited, and anything that you want to do when logging in (you might split this into interactive and non-interactive things under some situations). Depending on what a shell is being started for, you want it to do all, some, or none of these things.

A regular login shell does all of them and then prompts you for commands; an interactive subshell started as part of your login session should just do the per shell setup and then prompt for commands. A shell started when you do 'ssh host command' should do the environment initialization and then run the command you gave it. An xdm login shell should do the environment initialization, definitely skip the interactive login bits, and then either run a command or execute a shell script (depending on how xdm is set up). And a shell started via a shell script with '#!/path/to/shell' should normally do none of these.

(If your shell runs per user dotfiles when executing scripts, it is really hard to create reliable scripts; any user can innocently screw up your script's execution environment in many ways and then your script breaks for them and only them, often oddly. One consequence of this is that if your shell can import things like functions from the environment, you need a switch to turn this behavior off (or just default the import to off when running commands from a file).)

The way Unix shells should work is there should be an agreed on set of command line switches (respected by all shells) to turn on each of the three sorts of things. Programs that needed shells to do certain sorts of setup work could then supply the appropriate switches (and there would be default behaviors, such as doing per shell initialization when started with stdin as a tty). Everyone would be able to be explicit about what was going on and what was being done when; as a bonus we could easily solve the xdm problem, among other issues.

In the real world of Unix as it is today, shells resort to heuristics to tell these situations apart, which occasionally fail. And then we have xdm and its hacks. The situation is extremely unlikely to change now, although in theory a Linux distribution (or several of them) could sit down and bang some heads together over this.

By the way, I maintain that a direct corollary of this whole issue is that your shell should give startup files direct information about what environment the shell is running in (or thinks it's running in). This is especially the case if the shell always or nearly always runs some file. If you do not make this information available you force the authors of startup files to examine the environment and try to reverse engineer your heuristics, which is a losing proposition for any number of reasons.

(The minimum information you provide should be what startup files the shell is planning to run, but more information is better here.)

Written on 19 June 2011.
« My xdm heresy
What I need for stream decoding and encoding binary protocols »

Page tools: View Source, Add Comment.
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Sun Jun 19 01:15:09 2011
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.