Wednesday, May 4, 2016

Finding your $PATH

Finding your $PATH
..And other Environment Variables


When scripting, many users will develop a script on their own computer and get it all sweet just right.  However, when deploying the script with a management tool, such as JAMF Casper, the script may fail.  One of the primary reasons is the path to a command may not be available in the environment used to run your script.

What does that mean?  It means that those different commands you type in Terminal are applications that are saved in different folders on your computer.  Sometimes, the computer knows where to look for them, sometimes not. 

When you open Terminal, your session starts with some settings in place.  Those settings are saved in Environment variables seen by typing printenv in Terminal. 

MyMac$ printenv
TERM_PROGRAM=Apple_Terminal
TERM=xterm-256color
SHELL=/bin/bash
TMPDIR=/var/folders/0t/l5h4xta2m30z8brekdsm3_cp0l/T/
TERM_PROGRAM_VERSION=361.1
EDITOR=emacs
USER=tman
PATH=/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
PWD=/Users/tman/Documents/CODE/NewProject
LANG=en_US.UTF-8
XPC_FLAGS=0x0
XPC_SERVICE_NAME=0
HOME=/Users/tman
SHLVL=1


The PATH variable is the one we are interested in here.  We can see the defined path by running echo and the variable name. 

MyMac$ echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin


Here we have five different directories which can contain terminal commands.  Have you ever used diskutil or grep?  You can find out which directory a program is in by typing 'which' and the command name.

MyMac$ which grep
/usr/bin/grep
MyMac$ which diskutil
/usr/sbin/diskutil


which is actually a program itself.

MyMac$ which which
/usr/bin/which



So when you type a program to run, 'sudo' for example, the computer searches those directories in your PATH variable to find it.  Once it finds a program name that matches, it tries to run it for you.

Back to the original problem.  What happens when you run your nice script from an MDM?  Well, the PATH environment variable may not be set so the computer can't find the program you are referencing.  Say in your script, you are running

diskutil mount /tmp/Wonderapp.dmg
installer -pkg /Volumes/Wonderapp/Wonderapp.pkg -target / 

And that fails in your script when run through Casper or other MDM.  One possible reason is that when it runs from Casper, the Environment variables are not set so the computer can't find 'disktutil' or 'installer'. 

While you could define the path in the beginning of your script:

export PATH=$PATH:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin

The more common solution is to simply specify the full path to the program you are using. 

/usr/sbin/diskutil mount /tmp/Wonderapp.dmg
/usr/sbin/installer -pkg /Volumes/Wonderapp/Wonderapp.pkg -target /

You can see from the export line above how we add to the PATH variable.   The $PATH variable in the command means 'everything that's in PATH now' and add this other stuff to it.  If you have a directory with a command line tool you use which is not in your PATH, you can add it so you don't always need to type the full path to the program.  For example, I have a directory on my computer with programs I've written.  It's in /Users/tman/Documents/CODE/   So instead of specifying that path when I want to run one, I can simply add that directory to my PATH variable.

export PATH=$PATH:/Users/tman/Documents/CODE

Now when I run my app, the computer (or BASH actually) will 'look' into my CODE directory for that program.

SECURITY HINT: Many GreyBeards (old linux guys with long grey beards) will type the full path to 'sudo' and other programs that require passwords when running.  It's possible that someone puts a malicious copy of 'sudo' on your computer so when you try to run it and enter your password, it actually emails a copy of your password to them.  So the GreyBeards will always type /usr/bin/sudo to make sure the right copy is run and nobody has a second copy to run in it's place. 

Changes to your PATH variable, or other environment variables are only valid in that terminal session and are reset each time you open Terminal.  If you'd like that setting to stay, you need to add it to your bash_profile file.  That file, if it doesn't already exist, can be saved in your home directory. 

nano ~/.bash_profile

Notice the period before bash.  Any file that starts with a period is hidden from normal view. Add that same text as above.  

export PATH=$PATH:/Users/tman/Documents/CODE

Nano is a simple text editor.  You could edit with TextWrangler or another app, but since we're in the command line anyways....    Follow the on screen instructions to save and edit.  That command will automatically add my CODE directory to my path each time I start Terminal.


No comments:

Post a Comment