I create a symbolic link:

ln -s /tmp/folder1 /tmp/folder2

Then I go to /tmp/folder2 and run pwd:

$ cd /tmp/folder2/
$ pwd
/tmp/folder2
$ sudo pwd
/tmp/folder1 # <-- This is the odd part

Why does pwd with sudo give the original directory? I'm writing a bash script and need the absolute path of the current directory. With sudo I can't seem to be able to get the original directory.


Solution 1:

The pwd command is both a shell builtin and /bin/pwd. Under normal circumstances, the builtin will be run in preference to /bin/pwd. The pwd command can be called as pwd -L or pwd -P Both the builtin and /bin/pwd default to pwd -L from the man page

-L, --logical use PWD from environment, even if it contains symlinks

so when you run pwd you actually run pwd -L which in effect prints $PWD (if it exists). When you run sudo pwd, sudo only provides the environment variables that is has been told to pass on via env_keep directives. PWD is not normally in this list so sudo pwd has to work out where it is and in effect runs as pwd -P

-P, --physical avoid all symlinks

The way to solve the problem is to either use pwd -P if you consistently want the physical directory path or (as @Felix says ) to add PWD to the list of environment variables to keep via an env_keep directive in sudoers

env_keep += "PWD"  

Solution 2:

In bash, pwd is a builtin. /bin/pwd yields the same behavior as sudo pwd.

You will want to

  1. use sudo pwd -L, which only works if you
  2. include Defaults env_keep=PWD in your sudoers file