Reputation: 5321
Given two files:
generic/scripts/hello.sh
parent/scripts -> generic/scripts
Upon calling parent/scripts/hello.sh
from any location, I would like (in the script) to find the full path of the parent directory. In this case parent
.
The main issue is that parent/scripts/..
refers to generic
in unix. On the other hand, everything involving regexes is not generic and may be error prone.
Solutions that don't work:
`dirname $0`/..
realpath `dirname $0`/..
readlink -f `dirname $0`/..
`cd *something*/..; pwd`
`perl ... abs_path(...)`
All these will point to generic
and not parent
because of the symbolic link.
Everything involving regular expressions are not adaptable/generic, may fail for more complexes paths. There might be other ..
and symlinks in the path, you want the grand-parent, it's a directory name involving ..
, you call it via $PATH...
Moreover, I would like it to work in any case, even when it is called via $PATH
.
Any simple safe solution for this simple problem? I mean it's just getting the parent directory after all!
What I used:
dir=$( dirname $( cd `dirname $0` >/dev/null; pwd ) )
Dunno if it is perfect but it seems to behave as expected.
Upvotes: 8
Views: 13187
Reputation: 645
in bash you could do some string manipulation on $PWD
if that variable is available.
For pathname of parent directory, use:
${PWD%/*}
Other examples :
me@host:/tmp/bash_string/ma ni-pu_la/tion$ echo -e \
"\$PWD or \${PWD} : " $PWD \
"\n\${PWD##/*} : " ${PWD##/*} \
"\n\${PWD##*/} : " ${PWD##*/} \
"\n\${PWD#/*} : " ${PWD#/*} \
"\n\${PWD#*/} : " ${PWD#*/} \
"\n\${PWD%%/*} : " ${PWD%%/*} \
"\n\${PWD%%*/} : " ${PWD%%*/} \
"\n\${PWD%/*} : " ${PWD%/*} \
"\n\${PWD%*/} : " ${PWD%*/} \
"\n" # Gives :
$PWD or ${PWD} : /tmp/bash_string/ma ni-pu_la/tion
${PWD##/*} :
${PWD##*/} : tion
${PWD#/*} : tmp/bash_string/ma ni-pu_la/tion
${PWD#*/} : tmp/bash_string/ma ni-pu_la/tion
${PWD%%/*} :
${PWD%%*/} : /tmp/bash_string/ma ni-pu_la/tion
${PWD%/*} : /tmp/bash_string/ma ni-pu_la
${PWD%*/} : /tmp/bash_string/ma ni-pu_la/tion
Upvotes: 0
Reputation: 14853
I call my scipt with this: ../script1
and it has a relative call to ../relative/script2
`(cd $0/.. && pwd)`/relative/script2
is in script1
Upvotes: 0
Reputation: 1260
pushd $(dirname $0)
FOO=$(pwd)
popd
That gives you the absolute path of the directory that the script is running in.
Upvotes: 1
Reputation: 30803
Try this:
basename $(dirname $(dirname $0))
or perhaps just
$(dirname $(dirname $0))
It is unclear if you want parent
alone or its full path.
Upvotes: 5
Reputation: 29463
I would recommend
1) use pwd -P
which will always give you the physical path, and then navigate with relative path to the other palce This is most safe.
2) use pwd -L
Upvotes: 1