aboutsummaryrefslogtreecommitdiff
path: root/sh/shrc.d/ud.sh
blob: 259f31675d89e71d407b64d22dad0407e504cb11 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# Shortcut to step up the directory tree with an arbitrary number of steps,
# like cd .., cd ../.., etc
ud() {

    # Change the positional parameters from the number of steps given to a
    # "../../.." string
    set -- "$(

        # Check first argument, number of steps upward, default to 1
        # "0" is weird, but valid; "-1" however makes no sense at all
        steps=${1:-1}
        if [ "$steps" -lt 0 ] ; then
            printf >&2 'ud(): Invalid step count\n'
            exit 2
        fi

        # Check second argument, target directory, default to $PWD
        dirname=${2:-"$PWD"}

        # Append /.. to the target the specified number of times
        i=0
        while [ "$i" -lt "$steps" ] ; do
            dirname=${dirname%/}/..
            i=$((i+1))
        done

        # Check we have a target after all that
        if [ -z "$dirname" ] ; then
            printf >&2 'ud(): Destination construction failed\n'
            exit 1
        fi

        # Print the target
        printf '%s\n' "$dirname"
    )"

    # If the subshell printed nothing, return with failure
    [ -n "$1" ] || return

    # Try to change into the determined directory
    command cd -- "$@"
}