1

Over time, I've added bunches of stuff to my PATH and it's lookin' pretty awful. How can I clean this up or what's the proper way to "reformat" all of this?

export PATH="$PATH:~/scripts"
export PATH="$PATH:~/Downloads/android-sdk-mac_x86/platform-tools/adb"
export PATH=/opt/local/bin:/opt/local/sbin:$PATH
export PATH="$PATH:~/Downloads/android-sdk-mac_x86/platform-tools:~/Downloads/android-sdk-mac_x86/tools:~/Downloads/android-sdk-mac_x86/platform-tools/adb"
export PATH="$PATH:~/bin"
export PATH="$PATH:~/bin/subl"
export PATH="$PATH:~/.rvm/gems/ruby-1.9.3-head/gems/git-media-0.1.1/bin"

export PATH=$PATH:$HOME/bin:/Users/me/Downloads/android-sdk-mac_86/tools
export PATH=$PATH:$HOME/bin:/Users/me/Downloads/android-sdk-mac_86/platform-tools
export PATH=/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/X11/bin:/.rvm/scripts/rvm:/.rvm/scripts/rvm:/~/Downloads/android-sdk-mac_x86/tools/android:/~/Downloads/android-ndk-r7/:/~/Downloads/android-sdk-mac_x86/platform-tools
export CC=gcc-4.2
export PATH=~/Downloads/android-ndk-r7:$PATH
ANDROID_HOME=~/Downloads/android-sdk-mac_x86
export PATH=${PATH}:$ANDROIDHOME/platform-tools
1
  • 3
    I don't understand the question. Delete the lines you no longer need. Done. Apr 5, 2012 at 14:27

4 Answers 4

3

In Bash, you only need to export the variable once, not at each assignment. Remove export from all of your PATH assignments then put export PATH on a line by itself at the end. If you are just setting the variable once, like with CC, then export in front of it is fine. You could also export them using a single command such as with export PATH CC ANDROID_HOME.

The distribution tarball for Bash comes with several convenience functions for prepending or appending a path to a variable. I think they are in a contrib file called "pathfuncs". They can make your rc file much more readable.

  • add_path will add the entry to the end of the PATH variable
  • pre_path will add the entry to the beginning of the PATH variable
  • del_path will remove the entry from the PATH variable, wherever it is

If you specify a variable as the second argument, it will use that instead of PATH.

For convenience, here they are:

# is $1 missing from $2 (or PATH) ?
no_path() {
    eval "case :\$${2-PATH}: in *:$1:*) return 1;; *) return 0;; esac"
}
# if $1 exists and is not in path, append it
add_path () {
  [ -d ${1:-.} ] && no_path $* && eval ${2:-PATH}="\$${2:-PATH}:$1"
}
# if $1 exists and is not in path, prepend it
pre_path () {
  [ -d ${1:-.} ] && no_path $* && eval ${2:-PATH}="$1:\$${2:-PATH}"
}
# if $1 is in path, remove it
del_path () {
  no_path $* || eval ${2:-PATH}=`eval echo :'$'${2:-PATH}: |
    sed -e "s;:$1:;:;g" -e "s;^:;;" -e "s;:\$;;"`
}

If you add those to your bash startup file, you can add to your PATH like this:

pre_path $HOME/bin
add_path /sbin
add_path /usr/sbin

Or specify a different variable:

pre_path $HOME/man MANPATH
pre_path $HOME/share/man MANPATH
add_path /usr/local/man MANPATH
add_path /usr/share/man MANPATH

I use this method in my rc files putting the pre_paths first and the add_paths second. It makes all of my path changes easy to understand at a glance. Another benefit is that the lines are short enough that I can add a trailing comment on a line if necessary.

And since these are functions, you can use them interactively from the commend line, such as by saying add_path `pwd` to add the current directory to the path.


Edit: Fixing your supplied rc file with the functions above, I have this:

pre_path /opt/local/bin
pre_path /opt/local/sbin
pre_path ~/Downloads/android-ndk-r7

add_path ~/scripts
add_path ~/Downloads/android-sdk-mac_x86/platform-tools
add_path ~/Downloads/android-sdk-mac_x86/tools
add_path ~/Downloads/android-sdk-mac_x86/platform-tools/adb
add_path ~/bin
add_path ~/bin/subl
add_path ~/.rvm/gems/ruby-1.9.3-head/gems/git-media-0.1.1/bin
add_path $HOME/bin
add_path /Users/me/Downloads/android-sdk-mac_86/tools
add_path /Users/me/Downloads/android-sdk-mac_86/platform-tools
add_path /usr/local/bin
add_path /usr/bin
add_path /bin
add_path /usr/sbin
add_path /sbin
add_path /usr/X11/bin
add_path /.rvm/scripts/rvm
add_path /.rvm/scripts/rvm
add_path /~/Downloads/android-sdk-mac_x86/tools/android
add_path /~/Downloads/android-ndk-r7/
add_path /~/Downloads/android-sdk-mac_x86/platform-tools

ANDROID_HOME=~/Downloads/android-sdk-mac_x86
add_path $ANDROID_HOME/platform-tools

export PATH
export CC=gcc-4.2

You have some cleanup to do to remove duplicates and put things in a better order.

2

You don't need this

export PATH="$PATH:~/Downloads/android-sdk-mac_x86/platform-tools/adb"

since adb is an executable.

In this:

export PATH="$PATH:~/Downloads/android-sdk-mac_x86/platform-tools:~/Downloads/android-sdk-mac_x86/tools:~/Downloads/android-sdk-mac_x86/platform-tools/adb"

You could get rid of the stuff after the colon (a repeat of the above adb).

In this:

export

PATH=/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/X11/bin:/.rvm/scripts/rvm:/.rvm/scripts/rvm:/~/Downloads/android-sdk-mac_x86/tools/android:/~/Downloads/android-ndk-r7/:/~/Downloads/android-sdk-mac_x86/platform-tools

you are repeating platform-tools (last entry) and android (2nd last entry).

Try putting each PATH addition on one line and all the dups will jump out at you.

1

You can put all the path modifications on a single line as e.g.

export PATH="$PATH:~/scripts:~/bin:~/bin/subl"

etc, but that would not make it more readable.

In line 11, however, you more or less do the above. At least you unset all the path changes made in line 1-10, so you can just remove line 1-10. You can then merge later $PATH changes to contain it to a single line, but as I said, it will be a single incomprehensible line.

1

Just a quick thought: I'd probably write something like this:

function addpath() {
    [[ -d "$1" ]] || return 1

    print -rl ${(s.:.)PATH} | grep -q "$1"
    [[ $? != 0 ]] || return 1

    path+="$1"
}

Then I'd put my paths (separated by newlines) for each machine where this zsh config is running in a file like e.g. .zsh/paths.d/host1 and apply this function on every line of the selected file...

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .