$PWD variable equivalent of pwd -P

10,566

Solution 1

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).

Solution 2

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
/tmp/bar
$ echo $PWDP
/tmp/foo

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

function PWDP.get
{
    typeset p=$(pwd -P; echo .)
    .sh.value=${p%??}
}

Solution 3

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.

readlink

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

Example

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
/usr/bin/ack
$ readlink /home/saml/ack 
/usr/bin/ack
$ readlink $HOME/ack
/usr/bin/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
/home/saml

$ readlink -f $PWD
/home/saml

References

Share:
10,566

Related videos on Youtube

Brian Postow
Author by

Brian Postow

Updated on September 18, 2022

Comments

  • Brian Postow
    Brian Postow almost 2 years

    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.

    • Tim Kennedy
      Tim Kennedy almost 11 years
      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
  • Brian Postow
    Brian Postow almost 11 years
    I'd rather not have to change the directory, I thought that there was a variable for this already.
  • slm
    slm almost 11 years
    No variable exists in the way that you want it. See @StephaneChazelas answer too. He'll tell you the same thing.
  • slm
    slm almost 11 years
    @BrianPostow - not that I've ever seen. There is $CWD, but it suffers the same issue.
  • Stéphane Chazelas
    Stéphane Chazelas almost 11 years
    @BrianPostow, cd ., by definition, doesn't change the directory.
  • Stéphane Chazelas
    Stéphane Chazelas almost 11 years
    as a small note: that doesn't work if the (physical) current directory ends in newline characters.
  • jlliagre
    jlliagre almost 11 years
    @StephaneChazelas Answer updated with something to avoid this point but I have no doubt you'll find more issues with it ...
  • Stéphane Chazelas
    Stéphane Chazelas almost 11 years
    Ouch. Yes, I've updated with a simpler and more reliable alternative. Hope you don't mind.
  • jlliagre
    jlliagre almost 11 years
    @StephaneChazelas Much simpler indeed, thanks !