16

I'm working on an uninstaller script to delete the parent folder where the script is installed.

/usr/local/Myapplication/Uninstaller/uninstall.sh

So uninstall.sh has to do this:

rm- rf /usr/local/Myapplication

I can retrieve the folder where uninstall resides

SYMLINKS=$(readlink -f "$0")
UNINSTALL_PATH=$(dirname "$SYMLINKS")

But I'm still unsure of the pretty way to get the parent path. I thought of using sed to demove the "Uninstaller" part of this path, but is there an elegant way to get the path to Myapplication folder to delete it?

Thank you

mklement0
  • 382,024
  • 64
  • 607
  • 775
MangO_O
  • 393
  • 1
  • 3
  • 15
  • in your script: `cd "$(dirname "$0")" && cd .. && cd .. && [ -d Myapplication/Uninstaller ] && rm -rf Myapplication` (I added a check that the directory we are about to delete contains a subdir "Uninstaller", but you could maybe add a better check, for example of a necessary file within Myapplication ?). If you don't know Myapplication, then : `cd "$(dirname $0)" && cd .. && zepath="$(pwd)" && cd .. && [ -f "${zepath}/somefilesthathouldbehere" ] && rm -rf "${zepath}" ` – Olivier Dulac Nov 25 '13 at 17:24
  • See the famous [Can a Bash script tell what directory it's stored in?](http://stackoverflow.com/questions/59895/can-a-bash-script-tell-what-directory-its-stored-in) question, then `cd ..` from there. – Dan Dascalescu Aug 15 '15 at 11:38

8 Answers8

22

How about using dirname twice?

APP_ROOT="$(dirname "$(dirname "$(readlink -fm "$0")")")"

The quoting desaster is only necessary to guard against whitespace in paths. Otherwise it would be more pleasing to the eye:

APP_ROOT=$(dirname $(dirname $(readlink -fm $0)))
hidefromkgb
  • 5,834
  • 1
  • 13
  • 44
Boldewyn
  • 81,211
  • 44
  • 156
  • 212
  • This works but I'm kinda iffy on using dirname twice to acheive what I want. More for learning purpose is there a way to get it in a single command line? sure `APP_ROOT=$(dirname "``$(readlink -f "$0")``")` would work but is there any other way? – MangO_O Nov 25 '13 at 15:04
  • You don't need to be iffy about that. `dirname` is tailored to give you the part of the directory of a path. It is exactly the right tool to do so. I update the answer for the syntax. – Boldewyn Nov 25 '13 at 15:55
  • Note, this method is insecure for "ugly" names. A name like "-rm -rf" will break the desired behavior. Probably "." will, too. I don't know if that's the best way, but I've created a separate "correctness-focused" question here: http://stackoverflow.com/questions/40700119/get-parent-directory-for-a-file-in-bash – VasiliNovikov Nov 20 '16 at 04:07
6

I put this answer as comment at 2018. But since I got a great feedback about the effectiveness of the solution, I will share it here as well :

# dir of script 
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )";
# parent dir of that dir
PARENT_DIRECTORY="${DIR%/*}"
Abdennour TOUMI
  • 87,526
  • 38
  • 249
  • 254
5

Just get the parent of the parent directory:

my_app_path=$(dirname $(dirname $(readlink -f "$0")))
mihai_mandis
  • 1,578
  • 1
  • 10
  • 13
4

If you need an absolute path, then you need cd. Otherwise you can just use $(dirname $0)/..

cd $(dirname $0)/..
path=$(pwd)
cd - # go back
Sergey Fedorov
  • 2,169
  • 1
  • 15
  • 26
3

the ultimate simple way of getting the parent directory path:

PARENT_DIRECTORY="${PWD%/*}" 
thom
  • 2,294
  • 12
  • 9
  • 6
    This is the parent directory of the current directory, not where the script resides. To use this I'd have to CD to the script directory first so it's not in a way too elegant. – MangO_O Nov 26 '13 at 14:11
  • @MangO_O : So you need to replace PWD by script's dir : `DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"; PARENT_DIRECTORY="${DIR%/*}"` – Abdennour TOUMI Apr 14 '18 at 08:02
  • 1
    @AbdennourTOUMI your solution worked well for me, seems easier than the accepted answer – subelsky Mar 05 '20 at 13:56
  • Welcome @subelsky. I've added it as answer to make it more visible for others: https://stackoverflow.com/a/60559856/747579 – Abdennour TOUMI Mar 06 '20 at 08:08
2

Full path to parent dir of script, i.e. "/usr/local/bin/bla": export PARENT_OF_THIS_SCRIPT=$( cd $(dirname $0) ; pwd -P )

Just the most recent parent of script, i.e. "bla": export PARENT_DIR_OF_SCRIPT=$( cd $(dirname $0) ; pwd -P | xargs basename )

Joe Goggins
  • 1,328
  • 12
  • 10
1

Why don't you simply add ../ at the end of the path?

Pierre Arlaud
  • 4,040
  • 3
  • 28
  • 42
  • This wouldn't work with rm, UNINSTALL_PATH=$(dirname "$SYMLINKS")/../ is not the correct father path when used with the rm command – MangO_O Nov 25 '13 at 14:59
  • 3
    Also you'd need to add `/../`. And if, for whatever reason, `$UNINSTALL_PATH` is empty, `/../ == /` and you're wiping the hard drive. – Boldewyn Nov 25 '13 at 15:58
1

As $0 can have suprising behavior, here is a solution using BASH_SOURCE[0]:

#/bin/bash

PARENT_DIR=$(dirname $(dirname $(readlink -f "${BASH_SOURCE[0]}")))
Abdull
  • 26,371
  • 26
  • 130
  • 172