38

This is a shell script (.sh file). I need to create an absolute path based on the current directory. I know about pwd, but how do I concatenate it with another string? Here is an example of what I am trying to do:

"$pwd/some/path"
jarlh
  • 42,561
  • 8
  • 45
  • 63
egig
  • 4,370
  • 5
  • 29
  • 50

4 Answers4

65

Sounds like you want:

path="$(pwd)/some/path"

The $( opens a subshell (and the ) closes it) where the contents are executed as a script so any outputs are put in that location in the string.


More useful often is getting the directory of the script that is running:

dot="$(cd "$(dirname "$0")"; pwd)"
path="$dot/some/path"

That's more useful because it resolves to the same path no matter where you are when you run the script:

> pwd
~
> ./my_project/my_script.sh
~/my_project/some/path

rather than:

> pwd
~
> ./my_project/my_script.sh
~/some/path
> cd my_project
> pwd
~/my_project
> ./my_script.sh
~/my_project/some/path

More complex but if you need the directory of the current script running if it has been executed through a symlink (common when installing scripts through homebrew for example) then you need to parse and follow the symlink:

if [[ "$OSTYPE" == *darwin* ]]; then
  READLINK_CMD='greadlink'
else
  READLINK_CMD='readlink'
fi

dot="$(cd "$(dirname "$([ -L "$0" ] && $READLINK_CMD -f "$0" || echo "$0")")"; pwd)"

More complex and more requirements for it to work (e.g. having a gnu compatible readlink installed) so I tend not to use it as much. Only when I'm certain I need it, like installing a command through homebrew.

Michael Allen
  • 5,712
  • 3
  • 38
  • 63
  • 2
    While `$(pwd)` works, it's simpler (and marginally more efficient) to use `$PWD`, which is a POSIX-mandated shell variable. Good tip re determining the _running script's_ directory, but note that this may not work as expected if the script was invoked through a _symlink_. Unfortunately, there is no straightforward solution that's also portable. – mklement0 May 13 '15 at 02:33
  • 1
    True true, symlinks can make it more complex, I'll update it to show that. – Michael Allen May 14 '15 at 12:36
  • Thanks for updating. Because `readlink -f` reports the absolute target path even when the argument is _not_ a symlink, you could simplify to `dot=$(dirname -- "$(READLINK_CMD -f -- "$0")")`. Note that using `$OSTYPE` is not portable (`bash` and `zsh` have it, though). I've created a POSIX-compliant shell function [here](http://stackoverflow.com/a/29835459/45375). – mklement0 May 14 '15 at 13:27
7

Using the shell builtin pwd in a command substitution ($(...)) is an option, but not necessary, because all POSIX-compatible shells define the special $PWD shell variable that contains the current directory as an absolute path, as mandated by POSIX.

Thus, using $PWD is both simpler and more efficient than $(pwd):

"$PWD/some/path"  # alternatively, for visual clarity: "${PWD}/some/path"

However, if you wanted to resolve symlinks in the directory path, you DO need pwd, with its -P option:

"$(pwd -P)/some/path"

Note that POSIX mandates that $PWD contain an absolute pathname with symlinks resolved. In practice, however, NO major POSIX-like shell (bash, dash, ksh, zsh) does that - they all retain symbolic link components. Thus, the (POSIX-compliant) pwd -P is needed to resolve them.
Note that all said POSIX-like shells implement pwd as a builtin that supports -P.


Michael Allen's helpful answer points out that it's common to want to know the directory of where the running script is located.

The challenge is that the script file itself may be a symlink, so determining the true directory of origin is non-trivial, especially when portability is a must.
This answer (of mine) shows a solution.

mklement0
  • 382,024
  • 64
  • 607
  • 775
  • `$(env pwd)` is a portable alternative to `$(pwd -P)` – David Jones May 16 '18 at 09:45
  • 1
    @DavidJones: `pwd -P` _is_ portable [(POSIX-compliant](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/pwd.html)). The major POSIX-like shells implement it as a builtin (`bash`, `dash`, `ksh`, `zsh`). By contrast, `env pwd` executes the external-utility form of `pwd`, typically `/bin/pwd`. These implementations differ across platforms with respect to their default behavior: GNU `/bin/pwd` defaults to `-P`, but BSD/macOS `/bin/pwd` does not, so for portability you'd have to use `-P` as well, but there's no advantage to calling the external-utility form of `pwd` - it'll just be slower – mklement0 May 16 '18 at 12:40
1
wd=`pwd`
new_path="$wd/some/path"
ISanych
  • 21,590
  • 4
  • 32
  • 52
0

with "dirname $0" you can get dynamin path upto current run scipt. for example : your file is locateted in shell folder file name is xyz and there are anthor file abc to include in xyz file. so put in xyz file LIke:

       php   "`dirname $0`"/abc.php