18

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

2
  • 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}" Commented Nov 25, 2013 at 17:24
  • See the famous Can a Bash script tell what directory it's stored in? question, then cd .. from there. Commented Aug 15, 2015 at 11:38

8 Answers 8

27

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)))
3
  • 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
    Commented Nov 25, 2013 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
    Commented Nov 25, 2013 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: stackoverflow.com/questions/40700119/… Commented Nov 20, 2016 at 4:07
7

Just get the parent of the parent directory:

my_app_path=$(dirname $(dirname $(readlink -f "$0")))
5

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%/*}"
1
  • Not a fan of changing the directory just to get some information that readlink could provide.
    – BarryPye
    Commented Oct 31, 2023 at 23:59
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
3

the ultimate simple way of getting the parent directory path:

PARENT_DIRECTORY="${PWD%/*}" 
4
  • 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
    Commented Nov 26, 2013 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%/*}" Commented Apr 14, 2018 at 8:02
  • 1
    @AbdennourTOUMI your solution worked well for me, seems easier than the accepted answer
    – subelsky
    Commented Mar 5, 2020 at 13:56
  • Welcome @subelsky. I've added it as answer to make it more visible for others: stackoverflow.com/a/60559856/747579 Commented Mar 6, 2020 at 8: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 )

1

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

2
  • This wouldn't work with rm, UNINSTALL_PATH=$(dirname "$SYMLINKS")/../ is not the correct father path when used with the rm command
    – MangO_O
    Commented Nov 25, 2013 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
    Commented Nov 25, 2013 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]}")))

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