10

Suppose I have a bash file called myBash.bash. It resides in:

/myDirect/myFolder/myBash.bash

Now I want to use the string /myDirect/myFolder (the location of myBash.bash) inside the script. Is there a command I can use to find this location?

Edit: The idea is that I want to set-up a zip-folder with code that can be started by a bash script inside that zip-file. I know the relative file-paths of the code inside that zip-file, but not the absolute paths, and I need those. One way would be to hard-code in the path, or require the path of the file to be given as a variable. However I would find it easier if it was possible for the bash-file to figure out where it is on its own and then create the relevant paths to the other file from its knowledge of the structure of the zip-file.

  • 3
    This might be better suited for stackoverflow. Check these questions: stackoverflow.com/questions/4774054/… stackoverflow.com/questions/59895/…. – Sethos II Mar 17 '17 at 8:41
  • 1
    use how.? please clarify – Sergiy Kolodyazhnyy Mar 17 '17 at 8:46
  • 1
    @SethosII this question is totally on topic here – Zanna Mar 17 '17 at 8:47
  • 1
    I added more context to the question. I thought there might be an easy/obvious command to get the file-path of the file that is executing, but it seems the answer is at least non-obvious. – dimpol Mar 17 '17 at 9:10
  • 3
    @Zanna I don't say it's offtopic, i think it's just more appropriate and as shown with the links already asked and answered there multiple times. – Sethos II Mar 17 '17 at 9:16
15

You can get the full path like:

realpath "$0"

And as pointed out by Serg you can use dirname to strip the filename like this

dirname "$(realpath $0)"

or even better to prevent awkward quoting and word-splitting with difficult filenames:

temp=$( realpath "$0"  ) && dirname "$temp"

Much better than my earlier idea which was to parse it (I knew there would be a better way!)

realpath "$0" | sed 's|\(.*\)/.*|\1|'

Notes

  • realpath returns the actual path of a file
  • $0 is this file (the script)
  • s|old|new| replace old with new
  • \(.*\)/ save any characters before / for later
  • \1 the saved part
  • 1
    +1 for use of $0 and sed magic. But the said sed magic is really unnecessary when tools like dirname exist – Sergiy Kolodyazhnyy Mar 17 '17 at 9:42
  • 2
    you already have the answer , use realpath: realpath "$( dirname $0 )" I personally would use readlink but that's me: readlink -e $(dirname $0) – Sergiy Kolodyazhnyy Mar 17 '17 at 9:53
  • @Serg: Wouldn't dirname "$(realpath "$0")" be better? Usually one wants to know the parent directory of the referenced file instead of the parent directory of the symbolic link referring to said file. – David Foerster Mar 17 '17 at 14:22
  • 4
    @Serg "$(dirname "$(realpath "$0")")" is the most straightforward way. Quotes inside $() work as normal. – DepressedDaniel Mar 17 '17 at 20:01
  • @DepressedDaniel Did a bit of research online, you're right: $() being a subshell will allow having quotes outside. I wouldn't say it's as straightforward though, unless one realizes $() are all subshells – Sergiy Kolodyazhnyy Mar 17 '17 at 20:27
5

if the script is in your path you can use something like

$ myloc=$(dirname "$(which foo.sh)")
$ echo "$myloc"
/path/to/foo.sh

EDIT: after reading comments from Serg, this might be a generic solution which works whether the script is in your path or not.

myloc==$(dirname "$(realpath $0)")
dirname "$myloc"
  • which is more suitable for when script resides in one of the directories that are part of PATH variable. Use $0 from within a script, just like Zanna shows. But your answer is proper since you use dirname instead of messing with sed, hence +1 for that – Sergiy Kolodyazhnyy Mar 17 '17 at 9:38
4

The accepted answer seems perfect. Here's another way to do it:

cd "$(dirname "$0")"
/bin/pwd

/bin/pwd prints the real path of the directory, as opposed to the pwd builtin command.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.