Skip to content

Instantly share code, notes, and snippets.

@joevt
Last active March 9, 2025 06:55
Show Gist options
  • Save joevt/a4ef4cd2e1485d0dd595893007bdfd6a to your computer and use it in GitHub Desktop.
Save joevt/a4ef4cd2e1485d0dd595893007bdfd6a to your computer and use it in GitHub Desktop.

Revisions

  1. joevt revised this gist Jun 13, 2024. 1 changed file with 3 additions and 3 deletions.
    6 changes: 3 additions & 3 deletions KextUtil.sh
    Original file line number Diff line number Diff line change
    @@ -1,11 +1,11 @@
    #!/bin/bash
    # joevt Feb 10, 2024
    # joevt Jun 12, 2024

    #10.4 Tiger to 10.13 High Sierra
    #10.3 Panther to 10.13 High Sierra
    kextload=kextload

    # Later macOS versions
    command -v kextutil > /dev/null && kextload=kextutil
    command -v kextutil > /dev/null 2>&1 && kextload=kextutil

    getkextidentifier () {
    local thekextpath="$1"
  2. joevt revised this gist Feb 10, 2024. 1 changed file with 3 additions and 2 deletions.
    5 changes: 3 additions & 2 deletions KextUtil.sh
    Original file line number Diff line number Diff line change
    @@ -1,5 +1,5 @@
    #!/bin/bash
    # joevt May 9, 2023
    # joevt Feb 10, 2024

    #10.4 Tiger to 10.13 High Sierra
    kextload=kextload
    @@ -153,8 +153,9 @@ installkext () {
    local kextname
    kextname="$(basename "$thekextpath")"
    local kextinstalldir="/Library/Extensions"
    if ((dosystem)); then
    if ((dosystem)) || [[ ! -d /Library/Extensions ]] ; then
    kextinstalldir="/System/Library/Extensions"
    dosystem=1
    fi
    local kextidentifier
    kextidentifier="$(getkextidentifier "$thekextpath")"
  3. joevt revised this gist May 10, 2023. 1 changed file with 14 additions and 12 deletions.
    26 changes: 14 additions & 12 deletions KextUtil.sh
    Original file line number Diff line number Diff line change
    @@ -1,5 +1,5 @@
    #!/bin/bash
    # joevt May 8, 2023
    # joevt May 9, 2023

    #10.4 Tiger to 10.13 High Sierra
    kextload=kextload
    @@ -34,7 +34,7 @@ checkkext () {
    return 1
    fi
    else
    echo "# That's not a kext." 1>&2
    echo "# \"$kextname\" not a kext." 1>&2
    return 1
    fi
    else
    @@ -113,8 +113,8 @@ loadkext () {
    local kexttmpdir
    kexttmpdir="$(mktemp -d /tmp/KextUtil_XXXXXXX)"
    kextloadpath="$kexttmpdir/$kextname"
    sudo cp -R "$thekextpath" "kextloadpath"
    if ! fixkextpermissions "kextloadpath" ; then
    sudo cp -R "$thekextpath" "$kextloadpath"
    if ! fixkextpermissions "$kextloadpath" ; then
    return 1
    fi
    fi
    @@ -172,8 +172,8 @@ installkext () {
    local kexttmpdir
    kexttmpdir="$(mktemp -d /tmp/KextUtil_XXXXXXX)"
    kextloadpath="$kexttmpdir/$kextname"
    sudo cp -R "$thekextpath" "kextloadpath"
    if ! fixkextpermissions "kextloadpath" ; then
    sudo cp -R "$thekextpath" "$kextloadpath"
    if ! fixkextpermissions "$kextloadpath" ; then
    return 1
    fi

    @@ -187,22 +187,24 @@ installkext () {
    if ((dosystem)); then
    mountsystemrw
    fi
    sudo mv "kextloadpath" "$kextinstalldir"
    sudo mv "$kextloadpath" "$kextinstalldir"
    echo "# Installed ${kextname}."
    if ((doload)); then
    sudo "$kextload" "$kextinstalldir/$kextname"
    kextstat 2> /dev/null | grep "$kextidentifier"
    echo "# Loaded ${kextname}."
    fi
    }

    removekext () {
    local thekextpath="$1"
    checkkext "$thekextpath" || return 1
    if [[ -d "$thekextpath" ]]; then
    if [[ "$thekextpath" == /System/Library/* ]] ; then
    mountsystemrw
    fi
    sudo rm -R "$thekextpath"
    local kextname
    kextname="$(basename "$thekextpath")"
    if [[ "$thekextpath" == /System/Library/* ]] ; then
    mountsystemrw
    fi
    sudo rm -R "$thekextpath" && echo "# Removed ${kextname}." || echo "# Error removing ${kextname}."
    }

    rebuildkextcache () {
  4. joevt revised this gist May 9, 2023. 1 changed file with 92 additions and 54 deletions.
    146 changes: 92 additions & 54 deletions KextUtil.sh
    Original file line number Diff line number Diff line change
    @@ -1,5 +1,5 @@
    #!/bin/bash
    # joevt Jan 31, 2023
    # joevt May 8, 2023

    #10.4 Tiger to 10.13 High Sierra
    kextload=kextload
    @@ -10,7 +10,7 @@ command -v kextutil > /dev/null && kextload=kextutil
    getkextidentifier () {
    local thekextpath="$1"
    if [[ ! -f "$thekextpath/Contents/Info.plist" ]]; then
    echo "# Missing Info.plist" 1>&2
    echo "# Missing Info.plist." 1>&2
    return 1
    fi
    # Mac OS X 10.4 doesn't have PlistBuddy so just use perl
    @@ -30,74 +30,107 @@ checkkext () {
    if (( theerr == 0 )); then
    return 0
    else
    echo "# Missing CFBundleIdentifier" 1>&2
    echo "# Missing CFBundleIdentifier." 1>&2
    return 1
    fi
    else
    echo "# That's not a kext" 1>&2
    echo "# That's not a kext." 1>&2
    return 1
    fi
    else
    echo "# Missing Info.plist" 1>&2
    echo "# Missing Info.plist." 1>&2
    return 1
    fi
    else
    echo "# Expected a kext folder" 1>&2
    echo "# Expected a kext package directory." 1>&2
    return 1
    fi
    }

    unloadkext () {
    local thekextpath="$1"
    checkkext "$thekextpath" || return 1

    local kextname
    kextname="$(basename "$thekextpath")"
    #local kextsrcdir
    #kextsrcdir="$(dirname "$thekextpath")"
    local kexttmpdir
    kexttmpdir="$(mktemp -d /tmp/KextUtil_XXXXXXX)"
    local kextinstalldir="/Library/Extensions"
    local kextidentifier
    kextidentifier="$(getkextidentifier "$thekextpath")"

    echo "# kextname: $kextname"
    echo "# kextidentifier: $kextidentifier"
    if ( kextstat | grep -q "$kextidentifier" ); then
    while ( kextstat | grep -q "$kextidentifier" ); do
    echo "# Unloading $kextname"
    sleep 1
    if ( kextstat 2> /dev/null | grep -q "$kextidentifier" ); then
    while : ; do
    echo "# Unloading ${kextname}."
    sudo kextunload -b "$kextidentifier"
    ( kextstat 2> /dev/null | grep -q "$kextidentifier" ) || break
    sleep 1
    done
    echo "# $kextname is unloaded"
    echo "# Unloaded ${kextname}."
    else
    echo "# $kextname is not loaded"
    echo "# ${kextname} is not loaded."
    fi
    }

    checkkextpermissions () {
    local thekextpath="$1"
    checkkext "$thekextpath" || return 1
    badpermissions="$(find "$thekextpath" -exec ls -ld {} \; | sed -E '/drwxr-xr-x.* root *wheel /d ; /-rw.r-.r-..* root *wheel /d')"
    if (( $(printf "%s" "$badpermissions" | wc -l) == 0 )); then
    return 0
    fi
    echo "# Permissions are not correct for the following:" 1>&2
    echo "$badpermissions" 1>&2
    return 1
    }

    fixkextpermission () {
    fixkextpermissions () {
    local thekextpath="$1"
    checkkext "$thekextpath" || return 1
    if checkkextpermissions "$thekextpath" 2> /dev/null ; then
    echo "# Permissions are good. No changes were required."
    return 0
    fi
    sudo chown -R root:wheel "$thekextpath"
    sudo find "$thekextpath" -type d -exec /bin/chmod 0755 {} \;
    sudo find "$thekextpath" -type f -exec /bin/chmod 0644 {} \;
    if checkkextpermissions "$thekextpath" 2> /dev/null ; then
    echo "# Fixed permissions."
    return 0
    fi
    echo "# Could not fix permissions." 1>&2
    return 1
    }

    loadkext () {
    local thekextpath="$1"
    checkkext "$thekextpath" || return 1
    local kextname
    kextname="$(basename "$thekextpath")"
    #local kextsrcdir
    #kextsrcdir="$(dirname "$thekextpath")"
    local kexttmpdir
    kexttmpdir="$(mktemp -d /tmp/KextUtil_XXXXXXX)"
    sudo cp -R "$thekextpath" "$kexttmpdir/$kextname"
    fixkextpermission "$kexttmpdir/$kextname"
    unloadkext "$thekextpath"
    if ( sudo "$kextload" "$kexttmpdir/$kextname" ); then
    echo "# $kextname was loaded"

    local kextloadpath
    if fixkextpermissions "$thekextpath" > /dev/null 2>&1 ; then
    kextloadpath="$thekextpath"
    else
    echo "# Cannot fix permissions. Will load kext from temporary directory." 1>&2
    local kexttmpdir
    kexttmpdir="$(mktemp -d /tmp/KextUtil_XXXXXXX)"
    kextloadpath="$kexttmpdir/$kextname"
    sudo cp -R "$thekextpath" "kextloadpath"
    if ! fixkextpermissions "kextloadpath" ; then
    return 1
    fi
    fi

    unloadkext "$kextloadpath"
    if ( sudo "$kextload" "$kextloadpath" ); then
    echo "# Loaded ${kextname}."
    return 0
    else
    echo "# $kextname was not loaded." 1>&2
    return 1
    fi
    }

    mountsystemrw () {
    mount | grep ' on / ' | grep -q 'read-only' && sudo mount -uw /
    }

    installkext () {
    @@ -113,16 +146,12 @@ installkext () {
    fi
    shift 1
    done

    local thekextpath="$1"
    checkkext "$thekextpath" || return 1

    local kextname
    kextname="$(basename "$thekextpath")"
    #local kextsrcdir
    #kextsrcdir="$(dirname "$thekextpath")"
    local kexttmpdir
    kexttmpdir="$(mktemp -d /tmp/KextUtil_XXXXXXX)"
    local kextinstalldir="/Library/Extensions"
    if ((dosystem)); then
    kextinstalldir="/System/Library/Extensions"
    @@ -131,40 +160,49 @@ installkext () {
    kextidentifier="$(getkextidentifier "$thekextpath")"

    if ((doload)); then
    # unloadkext will do these echo lines for us:
    # echo "# kextname: $kextname"
    # echo "# kextidentifier: $kextidentifier"
    unloadkext "$thekextpath"
    else
    echo "# kextname: $kextname"
    echo "# kextidentifier: $kextidentifier"
    fi

    sudo cp -R "$thekextpath" "$kexttmpdir/$kextname"

    fixkextpermission "$kexttmpdir/$kextname"
    local kexttmpdir
    kexttmpdir="$(mktemp -d /tmp/KextUtil_XXXXXXX)"
    kextloadpath="$kexttmpdir/$kextname"
    sudo cp -R "$thekextpath" "kextloadpath"
    if ! fixkextpermissions "kextloadpath" ; then
    return 1
    fi

    if [[ -n "$kextinstalldir" ]]; then
    if [[ -d "/System/Library/Extensions/$kextname" ]]; then
    mount | grep ' on / ' | grep -q 'read-only' && sudo mount -uw /
    sudo rm -R "/System/Library/Extensions/$kextname"
    fi
    [[ -d "/Library/Extensions/$kextname" ]] && sudo rm -R "/Library/Extensions/$kextname"
    sudo mv "$kexttmpdir/$kextname" "$kextinstalldir"
    if ((doload)); then
    sudo "$kextload" "$kextinstalldir/$kextname"
    fi
    else
    if ((doload)); then
    sudo "$kextload" "$kexttmpdir/$kextname"
    fi
    if [[ -d "/System/Library/Extensions/$kextname" ]]; then
    mountsystemrw
    sudo rm -R "/System/Library/Extensions/$kextname"
    fi
    if [[ -d "/Library/Extensions/$kextname" ]]; then
    sudo rm -R "/Library/Extensions/$kextname"
    fi
    if ((dosystem)); then
    mountsystemrw
    fi
    sudo mv "kextloadpath" "$kextinstalldir"
    if ((doload)); then
    kextstat | grep "$kextidentifier"
    sudo "$kextload" "$kextinstalldir/$kextname"
    kextstat 2> /dev/null | grep "$kextidentifier"
    fi
    }

    removekext () {
    local thekextpath="$1"
    checkkext "$thekextpath" || return 1
    [[ -d "$thekextpath" ]] && sudo rm -R "$thekextpath"
    if [[ -d "$thekextpath" ]]; then
    if [[ "$thekextpath" == /System/Library/* ]] ; then
    mountsystemrw
    fi
    sudo rm -R "$thekextpath"
    fi
    }

    rebuildkextcache () {
  5. joevt revised this gist Feb 1, 2023. 1 changed file with 21 additions and 5 deletions.
    26 changes: 21 additions & 5 deletions KextUtil.sh
    Original file line number Diff line number Diff line change
    @@ -1,7 +1,10 @@
    #!/bin/bash
    # joevt Jan 6, 2023
    # joevt Jan 31, 2023

    #10.4 Tiger to 10.13 High Sierra
    kextload=kextload

    # Later macOS versions
    command -v kextutil > /dev/null && kextload=kextutil

    getkextidentifier () {
    @@ -92,15 +95,25 @@ loadkext () {
    sudo cp -R "$thekextpath" "$kexttmpdir/$kextname"
    fixkextpermission "$kexttmpdir/$kextname"
    unloadkext "$thekextpath"
    sudo "$kextload" "$kexttmpdir/$kextname"
    if ( sudo "$kextload" "$kexttmpdir/$kextname" ); then
    echo "# $kextname was loaded"
    fi
    }

    installkext () {
    local doload=0
    if [[ "$1" == "-l" ]]; then
    doload=1
    local dosystem=0
    while (( $# )); do
    if [[ "$1" == "-l" ]]; then
    doload=1
    elif [[ "$1" == "-s" ]]; then
    dosystem=1
    else
    break
    fi
    shift 1
    fi
    done

    local thekextpath="$1"
    checkkext "$thekextpath" || return 1

    @@ -111,6 +124,9 @@ installkext () {
    local kexttmpdir
    kexttmpdir="$(mktemp -d /tmp/KextUtil_XXXXXXX)"
    local kextinstalldir="/Library/Extensions"
    if ((dosystem)); then
    kextinstalldir="/System/Library/Extensions"
    fi
    local kextidentifier
    kextidentifier="$(getkextidentifier "$thekextpath")"

  6. joevt revised this gist Jan 6, 2023. 1 changed file with 4 additions and 4 deletions.
    8 changes: 4 additions & 4 deletions KextUtil.sh
    Original file line number Diff line number Diff line change
    @@ -1,5 +1,5 @@
    #!/bin/bash
    # joevt Dec 8, 2022
    # joevt Jan 6, 2023

    kextload=kextload
    command -v kextutil > /dev/null && kextload=kextutil
    @@ -53,7 +53,7 @@ unloadkext () {
    #local kextsrcdir
    #kextsrcdir="$(dirname "$thekextpath")"
    local kexttmpdir
    kexttmpdir="$(mktemp -d KextUtil_XXXXXXX)"
    kexttmpdir="$(mktemp -d /tmp/KextUtil_XXXXXXX)"
    local kextinstalldir="/Library/Extensions"
    local kextidentifier
    kextidentifier="$(getkextidentifier "$thekextpath")"
    @@ -88,7 +88,7 @@ loadkext () {
    #local kextsrcdir
    #kextsrcdir="$(dirname "$thekextpath")"
    local kexttmpdir
    kexttmpdir="$(mktemp -d KextUtil_XXXXXXX)"
    kexttmpdir="$(mktemp -d /tmp/KextUtil_XXXXXXX)"
    sudo cp -R "$thekextpath" "$kexttmpdir/$kextname"
    fixkextpermission "$kexttmpdir/$kextname"
    unloadkext "$thekextpath"
    @@ -109,7 +109,7 @@ installkext () {
    #local kextsrcdir
    #kextsrcdir="$(dirname "$thekextpath")"
    local kexttmpdir
    kexttmpdir="$(mktemp -d KextUtil_XXXXXXX)"
    kexttmpdir="$(mktemp -d /tmp/KextUtil_XXXXXXX)"
    local kextinstalldir="/Library/Extensions"
    local kextidentifier
    kextidentifier="$(getkextidentifier "$thekextpath")"
  7. joevt revised this gist Dec 8, 2022. 1 changed file with 67 additions and 23 deletions.
    90 changes: 67 additions & 23 deletions KextUtil.sh
    Original file line number Diff line number Diff line change
    @@ -1,13 +1,28 @@
    # by joevt Dec 30, 2020
    #!/bin/bash
    # joevt Dec 8, 2022

    kextload=kextload
    command -v kextutil > /dev/null && kextload=kextutil

    getkextidentifier () {
    local thekextpath="$1"
    if [[ ! -f "$thekextpath/Contents/Info.plist" ]]; then
    echo "# Missing Info.plist" 1>&2
    return 1
    fi
    # Mac OS X 10.4 doesn't have PlistBuddy so just use perl
    perl -0777 -n -e 'if (m|<key>CFBundleIdentifier</key>\s*<string>(.+)</string>|) { print $1 }' "$thekextpath/Contents/Info.plist"
    }

    checkkext () {
    local thekextpath="$1"
    if [[ -d "$thekextpath" ]]; then
    if [[ -f "$thekextpath/Contents/Info.plist" ]]; then
    local kextname="$(basename "$thekextpath")"
    if [[ "$kextname" =~ ".*\.kext" ]]; then
    local kextname
    kextname="$(basename "$thekextpath")"
    if grep -q -E "\.kext$" <<< "$kextname"; then
    local kextidentifier=""
    kextidentifier="$(/usr/libexec/PlistBuddy -c 'Print :CFBundleIdentifier' "$thekextpath/Contents/Info.plist" 2> /dev/null)"
    kextidentifier="$(getkextidentifier "$thekextpath")"
    local theerr=$?
    if (( theerr == 0 )); then
    return 0
    @@ -29,16 +44,19 @@ checkkext () {
    fi
    }


    unloadkext () {
    local thekextpath="$1"
    checkkext "$thekextpath" || return 1

    local kextname="$(basename "$thekextpath")"
    local kextsrcdir="$(dirname "$thekextpath")"
    local kexttmpdir="$(mktemp -d)"
    local kextname
    kextname="$(basename "$thekextpath")"
    #local kextsrcdir
    #kextsrcdir="$(dirname "$thekextpath")"
    local kexttmpdir
    kexttmpdir="$(mktemp -d KextUtil_XXXXXXX)"
    local kextinstalldir="/Library/Extensions"
    local kextidentifier="$(/usr/libexec/PlistBuddy -c 'Print :CFBundleIdentifier' "$thekextpath/Contents/Info.plist")"
    local kextidentifier
    kextidentifier="$(getkextidentifier "$thekextpath")"

    echo "# kextname: $kextname"
    echo "# kextidentifier: $kextidentifier"
    @@ -54,6 +72,28 @@ unloadkext () {
    fi
    }

    fixkextpermission () {
    local thekextpath="$1"
    checkkext "$thekextpath" || return 1
    sudo chown -R root:wheel "$thekextpath"
    sudo find "$thekextpath" -type d -exec /bin/chmod 0755 {} \;
    sudo find "$thekextpath" -type f -exec /bin/chmod 0644 {} \;
    }

    loadkext () {
    local thekextpath="$1"
    checkkext "$thekextpath" || return 1
    local kextname
    kextname="$(basename "$thekextpath")"
    #local kextsrcdir
    #kextsrcdir="$(dirname "$thekextpath")"
    local kexttmpdir
    kexttmpdir="$(mktemp -d KextUtil_XXXXXXX)"
    sudo cp -R "$thekextpath" "$kexttmpdir/$kextname"
    fixkextpermission "$kexttmpdir/$kextname"
    unloadkext "$thekextpath"
    sudo "$kextload" "$kexttmpdir/$kextname"
    }

    installkext () {
    local doload=0
    @@ -64,11 +104,15 @@ installkext () {
    local thekextpath="$1"
    checkkext "$thekextpath" || return 1

    local kextname="$(basename "$thekextpath")"
    local kextsrcdir="$(dirname "$thekextpath")"
    local kexttmpdir="$(mktemp -d)"
    local kextname
    kextname="$(basename "$thekextpath")"
    #local kextsrcdir
    #kextsrcdir="$(dirname "$thekextpath")"
    local kexttmpdir
    kexttmpdir="$(mktemp -d KextUtil_XXXXXXX)"
    local kextinstalldir="/Library/Extensions"
    local kextidentifier="$(/usr/libexec/PlistBuddy -c 'Print :CFBundleIdentifier' "$thekextpath/Contents/Info.plist")"
    local kextidentifier
    kextidentifier="$(getkextidentifier "$thekextpath")"

    if ((doload)); then
    unloadkext "$thekextpath"
    @@ -77,36 +121,36 @@ installkext () {
    echo "# kextidentifier: $kextidentifier"
    fi

    mount | grep ' on / ' | grep -q 'read-only' && sudo mount -uw /

    sudo cp -R "$thekextpath" "$kexttmpdir/$kextname"
    sudo chown -R root:wheel "$kexttmpdir/$kextname"
    sudo find "$kexttmpdir/$kextname" -type d -exec /bin/chmod 0755 {} \;
    sudo find "$kexttmpdir/$kextname" -type f -exec /bin/chmod 0644 {} \;

    fixkextpermission "$kexttmpdir/$kextname"

    if [[ -n "$kextinstalldir" ]]; then
    [[ -d "/System/Library/Extensions/$kextname" ]] && sudo rm -R "/System/Library/Extensions/$kextname"
    if [[ -d "/System/Library/Extensions/$kextname" ]]; then
    mount | grep ' on / ' | grep -q 'read-only' && sudo mount -uw /
    sudo rm -R "/System/Library/Extensions/$kextname"
    fi
    [[ -d "/Library/Extensions/$kextname" ]] && sudo rm -R "/Library/Extensions/$kextname"
    sudo mv "$kexttmpdir/$kextname" "$kextinstalldir"
    if ((doload)); then
    sudo kextutil "$kextinstalldir/$kextname"
    sudo "$kextload" "$kextinstalldir/$kextname"
    fi
    else
    if ((doload)); then
    sudo kextutil "$kexttmpdir/$kextname"
    sudo "$kextload" "$kexttmpdir/$kextname"
    fi
    fi
    if ((doload)); then
    kextstat | grep "$kextidentifier"
    fi
    }


    removekext () {
    local thekextpath="$1"
    checkkext "$thekextpath" || return 1
    [[ -d "$thekextpath" ]] && sudo rm -R "$thekextpath"
    }


    rebuildkextcache () {
    sudo kextcache -i /
    }
  8. joevt revised this gist Dec 31, 2020. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion KextUtil.sh
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    # joevt Dec 30, 2020
    # by joevt Dec 30, 2020

    checkkext () {
    local thekextpath="$1"
  9. joevt created this gist Dec 31, 2020.
    112 changes: 112 additions & 0 deletions KextUtil.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,112 @@
    # joevt Dec 30, 2020

    checkkext () {
    local thekextpath="$1"
    if [[ -d "$thekextpath" ]]; then
    if [[ -f "$thekextpath/Contents/Info.plist" ]]; then
    local kextname="$(basename "$thekextpath")"
    if [[ "$kextname" =~ ".*\.kext" ]]; then
    local kextidentifier=""
    kextidentifier="$(/usr/libexec/PlistBuddy -c 'Print :CFBundleIdentifier' "$thekextpath/Contents/Info.plist" 2> /dev/null)"
    local theerr=$?
    if (( theerr == 0 )); then
    return 0
    else
    echo "# Missing CFBundleIdentifier" 1>&2
    return 1
    fi
    else
    echo "# That's not a kext" 1>&2
    return 1
    fi
    else
    echo "# Missing Info.plist" 1>&2
    return 1
    fi
    else
    echo "# Expected a kext folder" 1>&2
    return 1
    fi
    }


    unloadkext () {
    local thekextpath="$1"
    checkkext "$thekextpath" || return 1

    local kextname="$(basename "$thekextpath")"
    local kextsrcdir="$(dirname "$thekextpath")"
    local kexttmpdir="$(mktemp -d)"
    local kextinstalldir="/Library/Extensions"
    local kextidentifier="$(/usr/libexec/PlistBuddy -c 'Print :CFBundleIdentifier' "$thekextpath/Contents/Info.plist")"

    echo "# kextname: $kextname"
    echo "# kextidentifier: $kextidentifier"
    if ( kextstat | grep -q "$kextidentifier" ); then
    while ( kextstat | grep -q "$kextidentifier" ); do
    echo "# Unloading $kextname"
    sleep 1
    sudo kextunload -b "$kextidentifier"
    done
    echo "# $kextname is unloaded"
    else
    echo "# $kextname is not loaded"
    fi
    }


    installkext () {
    local doload=0
    if [[ "$1" == "-l" ]]; then
    doload=1
    shift 1
    fi
    local thekextpath="$1"
    checkkext "$thekextpath" || return 1

    local kextname="$(basename "$thekextpath")"
    local kextsrcdir="$(dirname "$thekextpath")"
    local kexttmpdir="$(mktemp -d)"
    local kextinstalldir="/Library/Extensions"
    local kextidentifier="$(/usr/libexec/PlistBuddy -c 'Print :CFBundleIdentifier' "$thekextpath/Contents/Info.plist")"

    if ((doload)); then
    unloadkext "$thekextpath"
    else
    echo "# kextname: $kextname"
    echo "# kextidentifier: $kextidentifier"
    fi

    mount | grep ' on / ' | grep -q 'read-only' && sudo mount -uw /

    sudo cp -R "$thekextpath" "$kexttmpdir/$kextname"
    sudo chown -R root:wheel "$kexttmpdir/$kextname"
    sudo find "$kexttmpdir/$kextname" -type d -exec /bin/chmod 0755 {} \;
    sudo find "$kexttmpdir/$kextname" -type f -exec /bin/chmod 0644 {} \;
    if [[ -n "$kextinstalldir" ]]; then
    [[ -d "/System/Library/Extensions/$kextname" ]] && sudo rm -R "/System/Library/Extensions/$kextname"
    [[ -d "/Library/Extensions/$kextname" ]] && sudo rm -R "/Library/Extensions/$kextname"
    sudo mv "$kexttmpdir/$kextname" "$kextinstalldir"
    if ((doload)); then
    sudo kextutil "$kextinstalldir/$kextname"
    fi
    else
    if ((doload)); then
    sudo kextutil "$kexttmpdir/$kextname"
    fi
    fi
    if ((doload)); then
    kextstat | grep "$kextidentifier"
    fi
    }


    removekext () {
    local thekextpath="$1"
    [[ -d "$thekextpath" ]] && sudo rm -R "$thekextpath"
    }


    rebuildkextcache () {
    sudo kextcache -i /
    }