I want to use the $PWD variable in a script, but I want it to be the hardware path without symlinks. I know about /bin/pwd and pwd -P, but those aren't variables.

I know that I can use:

setenv MYPWD `pwd -P`

But I remember there being another way to do it.

  • some shells support $(pwd -P) syntax, as opposed to back ticks, but I don't think (t)csh is one (or two) of them. Also, for why you shouldn't script in (t)csh, see: shlomifish.org/open-source/anti/csh Aug 16, 2013 at 4:12

3 Answers 3


In POSIX shells, after

cd -P .

$PWD will contain a symlink-free path.

In zsh, $PWD:A will expand to the symlink-free version of $PWD (works for any variable, not just $PWD).

In zsh, setopt chase_links, and in tcsh, set symlinks = chase, cause cd to make sure $PWD is symlink-free. However, that only works after the first cd. In zsh, cd . will make $PWD symlink free, but not in tcsh where you'd need cd "$cwd" (which is not guaranteed to work).

  • I'd rather not have to change the directory, I thought that there was a variable for this already. Aug 15, 2013 at 16:18
  • @BrianPostow - not that I've ever seen. There is $CWD, but it suffers the same issue.
    – slm
    Aug 15, 2013 at 16:20
  • @BrianPostow, cd ., by definition, doesn't change the directory. Aug 15, 2013 at 20:19
  • cd -P appears to, even though you are in the same physical dir, the logical path changes. You can use pushd and popd to counter this.
    – Jamie Pate
    Sep 22, 2014 at 19:39

To my knowledge there is no such variable provided by the environment that will guarantee that its value is the physical path and not a linked version.

Given this your options are limited to the choices that you've already mentioned plus the following alternative.


You can use the command readlink to get the physical directory/file that a symbolic link is pointing to:


sample data:

$ ln -s /usr/bin/ack ack

$ ls -l |grep ack
lrwxrwxrwx   1 saml saml        12 Aug 15 11:48 ack -> /usr/bin/ack

physical location:

$ readlink ./ack
$ readlink /home/saml/ack 
$ readlink $HOME/ack

If the value you pass to readlink isn't a link it won't return anything. You can force it to return the canonical value by using the -f switch:

$ echo $PWD

$ readlink -f $PWD


  • A command doesn't help any. If I wanted a command I could just use /bin/pwd or pwd -P. I want a variable. Aug 15, 2013 at 16:18
  • 1
    No variable exists in the way that you want it. See @StephaneChazelas answer too. He'll tell you the same thing.
    – slm
    Aug 15, 2013 at 16:19

If you are using ksh93, there is a simple way to implement that variable. Just add this discipline function either at the beginning of your script or being sourced by it:

function PWDP.get
  .sh.value=$(pwd -P)

Then, you can just use the PWDP variable as you expect:

$ mkdir /tmp/foo
$ ln -s /tmp/foo /tmp/bar
$ cd /tmp/bar
$ echo $PWD
$ echo $PWDP

Edit, a "slightly" more complex solution trying to handle Stéphane Chazelas point:

function PWDP.get
    typeset p=$(pwd -P; echo .)
  • as a small note: that doesn't work if the (physical) current directory ends in newline characters. Aug 21, 2013 at 13:49
  • @StephaneChazelas Answer updated with something to avoid this point but I have no doubt you'll find more issues with it ...
    – jlliagre
    Aug 21, 2013 at 20:59
  • Ouch. Yes, I've updated with a simpler and more reliable alternative. Hope you don't mind. Aug 21, 2013 at 21:08
  • @StephaneChazelas Much simpler indeed, thanks !
    – jlliagre
    Aug 21, 2013 at 21:10

You must log in to answer this question.

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