I need to prepend directories to the path variable in my .cshrc file and I want to make sure that the entries are not repeated when compared to existing directories in the path variable. Can someone advise suitable commands for that? The path on my machine is : separated, not space separated.

  • I added a reply to complement Stephane answer with a way to "un-duplicate" the PATH automagically (while keeping important binary dirs up front!) – Olivier Dulac Jun 5 '13 at 15:25

If on Linux, I suppose your csh is tcsh. Then you should be able to do:

set -f path=("/new/entry" $path:q)

In csh, tcsh and zsh, the $path special array variable is tied to the $PATH scalar environment variable in that the elements of the $path array are constructed by splitting the $PATH variable on the colon character. Any modification of either $path or $PATH is automatically reflected into the other variable.

-f above is to retain only the first entry. $path:q is the elements of $path, quoted, that is preventing word splitting. So the syntax above prepends the /new/entry or moves it to the front if it was already there.

Why would you be using csh though?

Note: the quotes above are necessary. Or more precisely, all the characters in /new/entry need to be quoted one way or another.

set -f path=('/new/'\e"ntry" $path:q)

is OK.

set -f path=(/'new/entry' $path:q)

is not. You can always do it in two stages though:

set path=(/new/entry $path:q)
set -f path=($path:q)

(one of the reasons you may want to stay away from csh)

  • 1
    +1 for the "why would you be using csh though?" : please, all csh users, read : faqs.org/faqs/unix-faq/shell/csh-whynot (or the infamous 'Csh-programming considered harmful') – Olivier Dulac May 30 '13 at 16:31
  • @OlivierDulac That's an argument against csh for scripts, not against csh for interactive use. The real argument against (t)csh for interactive use is that zsh has surpassed tcsh for 20 years, and bash has surpassed tcsh for 10 years, so you should switch to software maintained this century. – Gilles 'SO- stop being evil' May 30 '13 at 22:49
  • Hi Stephane, thanks for a quick answer! The use of csh is not by choice in my case, it is decided by the tools that we use. Can you also suggest a way if the new additions to $PATH are several : delimited directories? Thanks! – astralsmith May 31 '13 at 7:08
  • @astralsmith, as I said, in (t)csh, the $path array variable is tied to the colon separated scalar variable $PATH. Modifying one will automatically update the other. – Stéphane Chazelas May 31 '13 at 7:32
  • Thanks Stephane. It works, although the entries are being repeated and not being moved to the front... – astralsmith May 31 '13 at 7:53

I believe that the following can do what you want.

if ( $PATH =~ */some/path* ) then
    set PATH = ($PATH:/some/path)

Note: I'm more of a bash user, so if I have a small error let me know
csh if test

  • Hi slm, it did not work in my case. I get "Bad : modifier in $ (/).". – astralsmith May 31 '13 at 11:58

I just add this as a complement to stephane answer: how to get rid of duplicates in $PATH

I'll assume you have

  • directories that should stay in front
  • and other directories as well, order not important (ie, placed AFTER the above)


To un-duplicate entries:

UNIQUE_LIST=$( echo "$PATH" | tr ':' '\n' | sort | uniq)

# then we place in front those from UNIQUELIST that match an ordered list
# note that that way, those who didn't have "/sbin" still won't have it, but if they did
# it will be at the right place in the list
shouldbefirst="/bin /sbin /usr/bin" # complete or re-order as needed on your system...
for dir in $shouldbefirst
   if ( echo "$UNIQUE_LIST" | grep "$dir" >/dev/null 2>/dev/null)
   then #we have this dir in UNIQUE_LIST
      UNIQUE_LIST="$( echo "$UNIQUE_LIST" | grep -v "^$dir\$")"  #we treated that one, take it out of the original list

# then put the remaining of UNIQUE_LIST in the order you want (here, alphabetically)
for dir in $UNIQUE_LIST
   UNIQUE_LIST="$( echo "$UNIQUE_LIST" | grep -v "^$dir\$")"  #we treated that one, take it out of the original list

 # get rid of possible first ":" (as NEWLIST starts empty)
 NEWLIST="$(echo "$NEWLIST" | sed -e 's/^://')"

 # and then : (I test by placing "echo" in front, get rid of "echo" if it looks fine)

(i can not test right now)

NOTE: I'll add recommendation: get rid of "." in your PATH, as it will be "bumped" up to just after the SHOULDBEFIRST dirs ... ("." should always be avoided, and if used, always in the last place only, so that you can't easily bypass commands from /bin, /usr/bin, etc)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.