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"
To determine the exact location of your current directory within the file system, go to a shell prompt and type the command pwd. This tells you that you are in the user sam's directory, which is in the /home directory. The command pwd stands for print working directory.
To determine the exact location of the current directory at a shell prompt and type the command pwd. This example shows that you are in the user sam's directory, which is in the /home/ directory. The command pwd stands for print working directory.
To reference a file, you need to provide the drive letter, the directory name (aka pathname) and the filename. For example, in " C:\Program Files\java\jdk1. 7.0_07\bin\javac.exe ", the drive letter is C: , the pathname is " \Program Files\java\jdk1.
The pwd command displays the full, absolute path of the current, or working, directory.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With