A few comments if you don’t mind…
You can find a lot about how a POSIX shell should work in the
latest POSIX/Open Group specs:
http://www.opengroup.org/onlinepubs/007904975/utilities/sh.html
There’s a good chance that our shell is not a perfect implementation
of what the standard requires – please report any bugs you
discover. There also are things that POSIX doesn’t cover – for
instance, I don’t think POSIX cares that the shell gets some of its
initial settings from an external file called /etc/profile.
Kevin Stallard <kevin@ffflyingrobots.com> wrote:
I’m posting this at the prompting of another QNX user (It’s qrm’s fault)
I’ve had the most terrible time trying to understand where to put
environment variables such that when I run a pterm they show up. Especially
the PS1 variable.
Seems there are a few others that don’t understand either. Well…if this
is you, this is your lucky day.
First some basics:
- When you login, the following occurs (there may be more stuff, but this
should be sufficient for this discussion.)
a. The $HOME variable is set from your home dir entry in the passwd
file (make sure this directory actually exists and that it is owned by you
and at least one of the groups to which you belong).
At this point, login execs into the shell.
Login sets the shell’s arguments so that argv[0] starts with a ‘-’
– that’s how shells traditionally recognize that they’re running as
a “login shell” and should run things like /etc/profile and
.profile. (The reason I’m mentioning this is because this also is
what pterm’s -l option does.)
b. /etc/profile is run. This is a script MAKE SURE it has execute
permissions.
/etc/profile is executed by your shell as a dot script. AFAIK, it
doesn’t need to have the execute permission (it doesn’t have it on
my machine).
c. $HOME/.profile script is run…make sure this also has execute
permissions (these two have been problems for me and others)
This one is also executed as a dot script. I’ve never needed to set
its execute permission, either.
d. A shell is started.
It’s started before step b.
e. Before the shell gives you a prompt, it looks for the environment
var ‘ENV’, if set with a proper file name, will try to execute the file as a
script.
Again, as a “dot script” (i.e. it does not spawn another shell,
which is done for regular scripts).
- One thing occurs when /etc/profile is run that is interesting. There is
a bit of code in there that attempts to set the $ENV variable.
You don’t need to care about this if your .profile overwrites ENV
with a new value. Mine does, and I had no idea that /etc/profile
tries to do that until a few days ago…
This is set if the name used to start your shell (with a ‘.’ in front)
exists as a script (with execute permissions) in your home directory. So,
if you use ksh and it was started using sh, and you are ‘root’, and you have
created a /root/.sh file (with execute permissions) ENV will be set to
‘/root/.sh’. Thus when a shell is invoked, that script will be run.
Unless your .profile changes it to run some other script instead.
This is important because there are some environment variables that get
overridden when the shell starts (i.e. PS1), so in order to get these, you
need to have a ‘.sh’ file that will set it for you. It isn’t good enough
for them to be in the $HOME/.profile script.
Hm… It seems to be good enough for me.
Now, what does this have to do with pterm?
Well…funny you should ask.
If you use the graphical login, it will run /etc/profile and
$HOME/.profile…you just won’t see it. Therefore it is important that if
you want to set a environment variable like ‘PS1’, you will need to create a
.sh file (or .bash if you are using bash (I think, I don’t use bash, so I
I don’t use bash either, but I vaguely remember that people had some
problems with phlogin when their default shell was bash. But that
was really long ago (under QNX4) and hopefully is fixed now.
can’t say)) in your home directory and give it execute permissions. Put the
required ‘export PS1=blah blah blah’ in .sh.
Like I said, defining PS1 in my .profile works for me.
Instead of relying on the code in /etc/profile that tries to find
your ~/.sh, I prefer to set ENV by hand in my .profile. This not
only lets me pick a name other than .sh for my file – it also seems
more portable (it even works under QNX4…).
Then when you start a pterm, the ‘.sh’ file will be executed and any
shifting environment variables can be set.
Note that there are many environment variables that will be inherited by the
shell from the execution of /etc/profile and $HOME/.profile (when you logged
into photon), so you don’t need to load ‘.sh’ with redundant stuff…
Are you suggesting that there are environment variables that are
not inherited and you have to set them in your $ENV file instead
of your .profile?
Like I said, setting environment variables in my .profile works for
me. I use the $ENV file for things that aren’t inherited, like
shell functions and aliases.
There’s one more thing worth mentioning: with our shell, the $ENV file
is executed by every shell you start, including non-interactive shells
that run your scripts or are spawned when your code calls system(). If
your $ENV file defines shell functions or aliases that change the
meaning of system commands (like alias rm=“rm -i”), this could break
some shell scripts or programs that expect the usual behaviour of those
commands. Also, if your $ENV file runs external programs, this could
significantly slow down programs that spawn a lot of shells (like make).
It’s wise to put code in your $ENV file to detect whether the shell that
executes it is interactive, and do as little as possible if it’s not.
As a side effect, this will make your environment more compatible with
future shells – the new Open Group specs say that $ENV should not be
looked at by a non-interactive shell, even though the previous version
of the specs did not make this distinction.
You can detect whether the shell is interactive by looking at the $-
variable. In an interactive shell, it will contain an ‘i’. For
instance, this is what I have in my $ENV file:
case “$-” in
i)
Do all the slow or dangerous stuff here
esac
–
Wojtek Lerch QNX Software Systems Ltd.