I use screen on a daily basis for my terminal needs and I'm quite happy with it. Recently, though, I made some updates to my bash configuration files and I noticed that I was setting various PATH
elements (PATH
, MANPATH
, INFOPATH
, etc) in 2 places. I modified the files to be what they should be and now all of my environment variables get set once in .bash_profile
. Herein lies my problem.
Apparently, the reason I was setting them in two places was because of screen. screen appears to only execute .bashrc
and does not appear to inherit my PATH
or any other environment variables correctly from my original bash shell. Because it only executes .bashrc
and I now set my variables in .bash_profile
only, I get an incomplete PATH
.
My question, then, is how to get my environment variables into screen without the duplication. Reading through the Bash
docs seems to indicate that it could be the kind of shell that screen uses to log in, i.e. a non-login interactive shell but I couldn't figure out how to force screen to use a particular kind of shell, only the shell to use via -s /bin/bash
.
You can peruse my config files at my GitHub page. This is the commit commit that broke screen.
EDIT: I'm using Screen version 4.00.03 (FAU) 23-Oct-06
and I tend to invoke it by screen -h 50000
EDIT: I've now been able to test this on Cygwin (CYGWIN_NT-5.1 1.7.1(0.218/5/3) i686
, Screen version 4.00.03 (FAU) 23-Oct-06
) and it exhibits different behavior than on my Mac.
The specific behavior that I've now discovered is that in Cygwin the changes that I make to PATH
in .bash_profile are duplicated upon entering screen and then successive creation of screen windows do not duplicate the path but do re-source .bash_profile.
To illustrate the behavior I'm talking about:
Output from a fresh terminal:
...
PATH: /home/tvishe01/bin/emacs/bin:/home/tvishe01/bin:/usr/local/bin:/usr/bin:/bin:/cygdrive/c/WINDOWS/system32:/cygdrive/c/WINDOWS:/cygdrive/c/WINDOWS/System32/Wbem:/cygdrive/c/Program Files/ATI Technologies/ATI.ACE/Core-Static:/groovy-1.6.1/bin:/usr/lib/lapack
MANPATH: /home/tvishe01/share/man:/usr/local/man:/usr/share/man:/usr/man::/usr/ssl/man
Aliases:
alias ..='cd ..'
alias ...='cd ../..'
...
[~]$
Output from the first invocation of screen:
[~]$ screen -h 50000 -s -/bin/bash
...
PATH: /home/tvishe01/bin/emacs/bin:/home/tvishe01/bin:/usr/local/bin:/usr/bin:/bin:/home/tvishe01/bin/emacs/bin:/home/tvishe01/bin:/usr/local/bin:/usr/bin:/bin:/cygdrive/c/WINDOWS/system32:/cygdrive/c/WINDOWS:/cygdrive/c/WINDOWS/System32/Wbem:/cygdrive/c/Program Files/ATI Technologies/ATI.ACE/Core-Static:/groovy-1.6.1/bin:/usr/lib/lapack
MANPATH: /home/tvishe01/share/man:/usr/local/man:/usr/share/man:/usr/man:/home/tvishe01/share/man:/usr/local/man:/usr/share/man:/usr/man::/usr/ssl/man:/usr/ssl/man
Aliases:
alias ..='cd ..'
alias ...='cd ../..'
...
[~]$
Subsequent calls to C-a c
:
...
PATH: /home/tvishe01/bin/emacs/bin:/home/tvishe01/bin:/usr/local/bin:/usr/bin:/bin:/home/tvishe01/bin/emacs/bin:/home/tvishe01/bin:/usr/local/bin:/usr/bin:/bin:/cygdrive/c/WINDOWS/system32:/cygdrive/c/WINDOWS:/cygdrive/c/WINDOWS/System32/Wbem:/cygdrive/c/Program Files/ATI Technologies/ATI.ACE/Core-Static:/groovy-1.6.1/bin:/usr/lib/lapack
MANPATH: /home/tvishe01/share/man:/usr/local/man:/usr/share/man:/usr/man:/home/tvishe01/share/man:/usr/local/man:/usr/share/man:/usr/man::/usr/ssl/man:/usr/ssl/man
Aliases:
alias ..='cd ..'
alias ...='cd ../..'
...
[~]$
You can see
Best Answer
screen and Environment Variables
By default, screen passes along to its shells (and other processes) whatever environment variables it had when the session was started (i.e. reconnecting does not change which environment variables are given to new shells). But because both screen and shells' configuration files commonly change environment variables, there are many places where unexpected changes can be introduced. There are a few variables, like TERM, that screen it almost always changes, but these are generally required for the functionality that screen provides.
Let's say that neither your shell's configuration, nor screen's configuration will modify a variable named FOOBAR (fairly likely, all in all). If you start a session with
FOOBAR=foo screen
, then all the shells created in that session will have an environment variable named FOOBAR with a value offoo
.Things get more complicated for variables that either screen or your shell might modify.
Missing Settings When Using screen
Login Shells
If you find that some settings are missing in shells started by screen, it may be because your shell is configured only to update those settings for ‘login’ shells. Most shells understand a special convention (in C:
**argv == '-'
) that screen can be configured to use.Per the screen documentation:
To have screen start shells as ‘login’ shells, start screen with
screen -s -/bin/bash
, or add this line to your.screenrc
:Adjust for the path to whatever shell you happen to be using.
screen Configuration
Missing or reset environment variables could also be due to
setenv
andunsetenv
commands in a screen configuration file. You will have to check both the .screenrc in your home directory and whichever file your compilation of screen is using as the ‘system screenrc’ (you might try a command likestrings "$(which screen)" | fgrep -i screenrc
to find the pathname that was configured at compile time–it is usually /etc/screenrc for a system-installed screen; add-on installations will probably use some other pathname). You can useSCREENRC=/dev/null SYSSCREENRC=/dev/null screen
to temporarily avoid these settings files, but there is a compile-time option that prevents the effective use of SYSSCREENRC (presumably so that system administrators can force some bit of initial configuration).Duplicate Settings When Using screen
It is fairly common to add items to an environment variable like PATH in a shell's configuration file(s) so that the updated value is available to normal shell sessions (e.g. xterm or other terminal windows, console sessions, etc.). If such items are added in a shell's per-shell configuration (or, if you are using the
-/path/to/shell
setting described above, in the shells per-login configuration) then the shell started by screen will likely have multiple copies of the added items.One strategy to avoid this is to put all additions to variables like PATH in the per-login configuration of your shell and avoid using the
-/path/to/shell
shell setting with screen.Another strategy is to only conditionally add the new items to the variable. Depending on the shell, the code to do this can be a bit complicated, but it can usually be encapsulated in a shell function for easy use.
Yet another strategy is to always start with a fixed value in your configuration files. This can sometimes cause problems when moving your configuration files from system to system when the default values might vary significantly.
Diagnostics
If you can not directly spot where a particular modification is happening, you can try the following to track down where the change is happening.
Check the current value in your initial shell:
Check how the shell itself modifies the value when a sub-shell is created:
Check how the shell modifies the value when a ‘login’ sub-shell is created:
Check how screen modifies the value: