-
Notifications
You must be signed in to change notification settings - Fork 25
Using a Shell Configuration File
When shells run they don't always execute a user's profile scripts. If a shell is a login shell (i.e., the first one that is run when a Terminal session is opened) then ~/.bash_profile
or ~/.profile
will be executed, depending on which exists, which shell is being used, etc.
If further shells are opened from this login shell, in which to enter commands (i.e., interactive shells), then the profile script is not run. However, if a shell configuration file is available (for example ~/.bashrc
for Bash) then that file is run. This is the file which by convention contains aliases and functions.
Finally, if a script is run then the shell that is created for the duration of that script will not cause any of these configuration scripts to run.
Bash checks for the environment variable ENV
when running as /bin/sh
, and if the variable is present the script referred to is executed.
A 'common' configuration therefore is to have settings and shell commands that are executed when creating interactive shells, in ~/.bashrc
, and settings and shell commands that apply only to login shells, in ~/.bash_profile
or ~/.profile
. To avoid duplication the commands for interactive shells can be executed from the login scripts. To illustrate, a ~/.bash_profile
file might look like this:
# Setup a reference to the configuration for interactive shells:
#
export BASH_ENV=~/.bashrc
export ENV=$BASH_ENV
# If the file referred to exists then run it:
#
if [ -f $BASH_ENV ]; then . $BASH_ENV; fi
and the related ~/.bashrc
file might look like this:
ls ()
{
ls -al $@
}
Of the various possible permutations of shells, ShellCommand
creates a non-interactive, non-login shell to run its commands. This avoids:
- executing any profile scripts, which may contain a lot more functionality than is necessary for a small command;
- creating an interactive shell, which does all sorts of additional things, such as checking for email.
However, this does mean that if we want any settings that are used in interactive shells we need to load them, since Bash won't do it for us. For this reason, just before the required command is run ShellCommand
checks the environment variable ENV
to locate any interactive shell script, and if the variable is present the script referred to is executed.
Note that when running Sublime on Mac OS via its icon, the ENV
value is not propagated through. This is a 'feature' of Mac OS rather than Sublime, and there are two ways around this. The first is to use the launchctl
command in profile scripts to make specific environment variables available to GUI applications:
# Setup a reference to the configuration for interactive shells:
#
export BASH_ENV=~/.bashrc
export ENV=$BASH_ENV
launchctl setenv BASH_ENV $BASH_ENV
launchctl setenv ENV $ENV
# If the file referred to exists then run it:
#
if [ -f $BASH_ENV ]; then . $BASH_ENV; fi
The second technique is to use the shell_configuration_file
option in settings, which can refer to a script to execute before each command. For example:
{
"shell_configuration_file": "~/.sublime_functions"
}
The ~/.sublime_functions
script might contain:
st ()
{
git status
}
For some reason aliases don't work within shells created in Python, but functions do. There are some suggestions that functions are preferred over aliases anyway, but regardless of whether that's true or not, any aliases that are needed within ShellCommand
would have to be mapped to functions. So this:
alias ls=ls -al
would need to become this:
function ls ()
{
ls -al $@
}
or this (since function
is optional):
ls ()
{
ls -al $@
}
Note that with aliases, anything on the command-line that appears after a matched alias will be passed through after the alias is switched in, but with functions we need to add $@
to pick up any remaining parameters.