[Pythonmac-SIG] Running Python scripts without full paths

Nicholas Riley njriley@uiuc.edu
Sat, 30 Nov 2002 13:33:52 -0600


On Sat, Nov 30, 2002 at 10:34:37AM -0800, Paul Berkowitz wrote:
> That's it! Thanks, Nicholas. yes, that's where python and python2.2 are in
> OS 10.2.2. I've wondered about that, I must say; it seems odd for something
> called "usr" to be computer-wide (local), but that's where it is.

I'm pretty sure that home directories used to be /usr/<uid> - at least
I've seen such things in old books - instead of being in /usr/home or
/home or /Users wherever they are now.  Most BSDs (though not Mac OS
X) have a 'bin' user, so in some bizarre way I guess you could
consider /usr/bin to be bin's home directory.  Though on FreeBSD where
I checked, bin's home directory is /, so that dashes that theory. :-)
Eventually you just learn these things and don't bother asking why any
more...  Check the hier(7) man page for a quick overview.

> What's the approved way to add a directory to the existing PATH environment
> variable, in the Terminal (tcsh) of Mac OS 10.2, in a way that will be
> "permanent" - will be operative in all future calls in Terminal windows?

Before taking Terminal out of the picture, understand what it does
when you create a new Terminal window.  This is a lot clearer in 10.2
than it was in earlier versions - see Terminal Preferences.  By
default 10.2's Terminal will run 'login', which executes your default
shell (as well as printing the MOTD and other such login-type
activities), or it'll run whatever command you specify in Preferences.
If the command happens to be a shell, then that shell will also be a
login shell.  Personally I have the 'execute this command' set to be
/bin/zsh because I don't want the additional overhead of 'login'.

>     set path=($path /Users/berkowit/Library/Scripts/Python)
> 
> and that actually works, and resets PATH too, as I can see when I printenv.

Yes, that's one of the weirdnesses of tcsh.  Something set by setenv
or set is only set in that shell until the next time you set/setenv
that variable.  The shell's environment is inherited by processes you
start from it.

If you want to see the starting environment of a process, try 'ps
-eww'.  For example, here it is for the zsh process Terminal just
started (to display that for the shell you're in now, try 'ps -Teww').

14555 std  Rs     0:00.76 -zsh HOME=/Users/nicholas SHELL=/bin/zsh USER=nicholas PATH=/usr/bin:/bin:/usr/sbin:/sbin:/Users/nicholas RSYNC_RSH=ssh QDTEXT_ANTIALIASING=1 QDTEXT_MINSIZE=14 OMNI_INSTALLED_PRODUCTS=/Users/nicholas/Library/Frameworks DISPLAY=localhost SSH_ASKPASS=/Applications/Utilities/SSHPassKey.app/Contents/MacOS/SSHPassKey CVS_RSH=ssh __CF_USER_TEXT_ENCODING=0x1F5:0:0 TERM=vt100 TERMCAP=M-??M-V  TERM_PROGRAM=Apple_Terminal TERM_PROGRAM_VERSION=81     (zsh)

Note that this is not the -current- environment of the zsh process,
which you can display with 'printenv'.  The ps process that produced
the above, however, inherited the shell's current environment.  The
zsh process received its initial environment from its parent process,
Terminal (if you use login, then the shell's parent process will
be login, and login's parent process will be Terminal).

The reason for ~/.MacOSX/environment.plist being necessary is that
shells are not the parent processes of normally launched GUI apps on
OS X: the WindowServer is.  Look at Terminal as an example:

% ps -ejwwp 481
USER       PID  PPID  PGID   SESS JOBC STAT  TT       TIME COMMAND
nicholas   481   251   251 2787a38    0 S     ??   42:04.23 /Applications/Utilities/Terminal.app/Contents/MacOS/Terminal -psn_0_2752513 HOME=/Users/nicholas SHELL=/bin/zsh USER=nicholas PATH=/usr/bin:/bin:/usr/sbin:/sbin:/Users/nicholas RSYNC_RSH=ssh QDTEXT_ANTIALIASING=1 QDTEXT_MINSIZE=14 OMNI_INSTALLED_PRODUCTS=/Users/nicholas/Library/Frameworks DISPLAY=localhost SSH_ASKPASS=/Applications/Utilities/SSHPassKey.app/Contents/MacOS/SSHPassKey CVS_RSH=ssh       
% ps -ejwwp 251
USER       PID  PPID  PGID   SESS JOBC STAT  TT       TIME COMMAND
nicholas   251     1   251 2787a38    0 Ss    ??   98:28.04 /System/Library/CoreServices/WindowServer -daemon PWD=/ SHLVL=1 PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/libexec:/System/Library/CoreServices _=/System/Library/CoreServices/WindowServer       
% pl < .MacOSX/environment.plist
{
    "CVS_RSH" = ssh; 
    DISPLAY = localhost; 
    "OMNI_INSTALLED_PRODUCTS" = "/Users/nicholas/Library/Frameworks"; 
    "QDTEXT_ANTIALIASING" = 1; 
    "QDTEXT_MINSIZE" = 14; 
    "RSYNC_RSH" = ssh; 
    "SSH_ASKPASS" = "/Applications/Utilities/SSHPassKey.app/Contents/MacOS/SSHPassKey"; 
}

Most of Terminal's environment is what is in ~/.MacOSX/environment.plist.
That file is only read on login, which is a real pain, but until
there's some way to force WindowServer to reread it, you're stuck with
trial and error.  A temporary workaround is to run the app you want
directly from the shell instead of using LaunchServices to do it (as
with the 'open' command, the Finder, etc.)  The 'pythonw' script does
exactly this.

> But the next day, after opening a new Terminal session, the new directory is
> gone. That _may_ be because I had a kernel panic late last night and had to
> force-restart the computer. Is it? In any case, I hope you don't mind my
> newbie questions - I'd like to know the best way of doing this. None of my
> Unix books tell me, because they are annoyed that every Unix system does it
> a different way, and just give up. How do we do it in OS X's BSD?

tcsh is the same program (pretty much) on all platforms where it runs,
and reads its config files the same way.  There's not much magic going
on if you understand it.

-- 
=Nicholas Riley <njriley@uiuc.edu> | <http://www.uiuc.edu/ph/www/njriley>
        Pablo Research Group, Department of Computer Science and
  Medical Scholars Program, University of Illinois at Urbana-Champaign