From 4abafc55ef7421be1d64d593ccff2068c1d82699 Mon Sep 17 00:00:00 2001 From: John D Pell Date: Sat, 1 Jan 2022 17:46:11 -0800 Subject: [PATCH 1/6] tests: quote paths --- test/run | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/run b/test/run index fe4ac847..7999d4fb 100755 --- a/test/run +++ b/test/run @@ -11,7 +11,7 @@ if [ -z "${BASH_IT}" ]; then fi if [ -z "$1" ]; then - test_dirs=( ${test_directory}/{bash_it,completion,install,lib,plugins,themes} ) + test_dirs=( "${test_directory}"/{bash_it,completion,install,lib,plugins,themes} ) else test_dirs=( "$1" ) fi From 75aabd5d201864146499abaf4d3123e65d5f8fbd Mon Sep 17 00:00:00 2001 From: John D Pell Date: Thu, 12 Aug 2021 12:13:58 -0700 Subject: [PATCH 2/6] plugin/osx: `shellcheck` && `shfmt` plugins/osx: dead code removal No need for gymnastics to determine if variable had been exported priort to modification. If it was, then it still is. See man bash(1). --- clean_files.txt | 1 + plugins/available/osx.plugin.bash | 231 ++++++++++++++---------------- 2 files changed, 112 insertions(+), 120 deletions(-) diff --git a/clean_files.txt b/clean_files.txt index 8c8b3fed..a70a44c2 100644 --- a/clean_files.txt +++ b/clean_files.txt @@ -103,6 +103,7 @@ plugins/available/jump.plugin.bash plugins/available/less-pretty-cat.plugin.bash plugins/available/node.plugin.bash plugins/available/nodenv.plugin.bash +plugins/available/osx.plugin.bash plugins/available/percol.plugin.bash plugins/available/plenv.plugin.bash plugins/available/pyenv.plugin.bash diff --git a/plugins/available/osx.plugin.bash b/plugins/available/osx.plugin.bash index ca1f66b8..555de8a3 100644 --- a/plugins/available/osx.plugin.bash +++ b/plugins/available/osx.plugin.bash @@ -1,23 +1,16 @@ -cite about-plugin +# shellcheck shell=bash about-plugin 'osx-specific functions' # OS X: Open new tabs in same directory -if [[ $OSTYPE == 'darwin'* ]]; then - if type update_terminal_cwd > /dev/null 2>&1 ; then - if ! [[ $PROMPT_COMMAND =~ (^|;)update_terminal_cwd($|;) ]] ; then - PROMPT_COMMAND="${PROMPT_COMMAND%;};update_terminal_cwd" - declared="$(declare -p PROMPT_COMMAND)" - [[ "$declared" =~ \ -[aAilrtu]*x[aAilrtu]*\ ]] 2>/dev/null - [[ $? -eq 0 ]] && export PROMPT_COMMAND - fi - fi +if _is_function update_terminal_cwd; then + safe_append_prompt_command 'update_terminal_cwd' fi function tab() { - about 'opens a new terminal tab' - group 'osx' + about 'opens a new terminal tab' + group 'osx' - osascript 2>/dev/null < /dev/null << EOF tell application "System Events" tell process "Terminal" to keystroke "t" using command down end @@ -30,147 +23,145 @@ EOF # renames the current os x terminal tab title function tabname { - printf "\e]1;$1\a" + printf '%b' "\e]1;$1\a" } # renames the current os x terminal window title function winname { - printf "\e]2;$1\a" + printf '%b' "\e]2;$1\a" } # this one switches your os x dock between 2d and 3d # thanks to savier.zwetschge.org function dock-switch() { - about 'switch dock between 2d and 3d' - param '1: "2d" or "3d"' - example '$ dock-switch 2d' - group 'osx' + about 'switch dock between 2d and 3d' + param '1: "2d" or "3d"' + example '$ dock-switch 2d' + group 'osx' - if [[ "$OSTYPE" = 'darwin'* ]]; then - - if [[ $1 = 3d ]] ; then - defaults write com.apple.dock no-glass -boolean NO - killall Dock - - elif [[ $1 = 2d ]] ; then - defaults write com.apple.dock no-glass -boolean YES - killall Dock - - else - echo "usage:" - echo "dock-switch 2d" - echo "dock-switch 3d." - fi - else - echo "Sorry, this only works on Mac OS X" - fi + case $OSTYPE in + *'darwin'*) + case $1 in + 3d) + defaults write com.apple.dock no-glass -boolean NO + killall Dock + ;; + 2d) + defaults write com.apple.dock no-glass -boolean YES + killall Dock + ;; + *) + echo "usage:" + echo "dock-switch 2d" + echo "dock-switch 3d." + ;; + esac + ;; + *) + echo "Sorry, this only works on Mac OS X" + ;; + esac } -function pman () -{ - about 'view man documentation in Preview' - param '1: man page to view' - example '$ pman bash' - group 'osx' - man -t "${1}" | open -fa $PREVIEW +function pman() { + about 'view man documentation in Preview' + param '1: man page to view' + example '$ pman bash' + group 'osx' + man -t "${1}" | open -fa 'Preview' } -function pri () -{ - about 'display information about Ruby classes, modules, or methods, in Preview' - param '1: Ruby method, module, or class' - example '$ pri Array' - group 'osx' - ri -T "${1}" | open -fa $PREVIEW +function pri() { + about 'display information about Ruby classes, modules, or methods, in Preview' + param '1: Ruby method, module, or class' + example '$ pri Array' + group 'osx' + ri -T "${1}" | open -fa 'Preview' } # Download a file and open it in Preview function prevcurl() { - about 'download a file and open it in Preview' - param '1: url' - group 'osx' + about 'download a file and open it in Preview' + param '1: url' + group 'osx' - if [[ ! $OSTYPE = 'darwin'* ]] - then - echo "This function only works with Mac OS X" - return 1 - fi - curl "$*" | open -fa $PREVIEW + if [[ ! $OSTYPE = 'darwin'* ]]; then + echo "This function only works with Mac OS X" + return 1 + fi + curl "$*" | open -fa 'Preview' } function refresh-launchpad() { - about 'Reset launchpad layout in macOS' - example '$ refresh-launchpad' - group 'osx' + about 'Reset launchpad layout in macOS' + example '$ refresh-launchpad' + group 'osx' - if [[ "$OSTYPE" = 'darwin'* ]];then - defaults write com.apple.dock ResetLaunchPad -bool TRUE - killall Dock - else - echo "Sorry, this only works on Mac OS X" - fi + if [[ "$OSTYPE" = 'darwin'* ]]; then + defaults write com.apple.dock ResetLaunchPad -bool TRUE + killall Dock + else + echo "Sorry, this only works on Mac OS X" + fi } -function list-jvms(){ - about 'List java virtual machines and their states in macOS' - example 'list-jvms' - group 'osx' +function list-jvms() { + about 'List java virtual machines and their states in macOS' + example 'list-jvms' + group 'osx' - JVMS_DIR="/Library/Java/JavaVirtualMachines" - JVMS=( $(ls ${JVMS_DIR}) ) - JVMS_STATES=() + local JVMS_DIR="/Library/Java/JavaVirtualMachines" + # The following variables are intended to impact the enclosing scope, not local. + JVMS=("${JVMS_DIR}"/*) + JVMS_STATES=() - # Map state of JVM - for (( i = 0; i < ${#JVMS[@]}; i++ )); do - if [[ -f "${JVMS_DIR}/${JVMS[$i]}/Contents/Info.plist" ]]; then - JVMS_STATES[${i}]=enabled - else - JVMS_STATES[${i}]=disabled - fi - echo "${i} ${JVMS[$i]} ${JVMS_STATES[$i]}" - done + # Map state of JVM + for ((i = 0; i < ${#JVMS[@]}; i++)); do + if [[ -f "${JVMS[i]}/Contents/Info.plist" ]]; then + JVMS_STATES[i]=enabled + else + JVMS_STATES[i]=disabled + fi + printf '%s\t%s\t%s\n' "${i}" "${JVMS[i]##*/}" "${JVMS_STATES[i]}" + done } -function pick-default-jvm(){ - about 'Pick the default Java Virtual Machines in system-wide scope in macOS' - example 'pick-default-jvm' +function pick-default-jvm() { + about 'Pick the default Java Virtual Machines in system-wide scope in macOS' + example 'pick-default-jvm' - # Call function for listing - list-jvms + # Declare variables + local JVMS JVMS_STATES + local DEFAULT_JVM_DIR DEFAULT_JVM OPTION - # Declare variables - local DEFAULT_JVM_DIR="" - local DEFAULT_JVM="" - local OPTION="" + # Call function for listing + list-jvms - # OPTION for default jdk and set variables - while [[ ! "$OPTION" =~ ^[0-9]+$ || OPTION -ge "${#JVMS[@]}" ]]; do - read -p "Enter Default JVM: " OPTION - if [[ ! "$OPTION" =~ ^[0-9]+$ ]]; then - echo "Please enter a number" - fi + # OPTION for default jdk and set variables + while [[ ! "$OPTION" =~ ^[0-9]+$ || OPTION -ge "${#JVMS[@]}" ]]; do + read -rp "Enter Default JVM: " OPTION + if [[ ! "$OPTION" =~ ^[0-9]+$ ]]; then + echo "Please enter a number" + fi - if [[ OPTION -ge "${#JVMS[@]}" ]]; then - echo "Please select one of the displayed JVMs" - fi - done + if [[ OPTION -ge "${#JVMS[@]}" ]]; then + echo "Please select one of the displayed JVMs" + fi + done - DEFAULT_JVM_DIR="${JVMS_DIR}/${JVMS[$OPTION]}" - DEFAULT_JVM="${JVMS[$OPTION]}" + DEFAULT_JVM_DIR="${JVMS[OPTION]}" + DEFAULT_JVM="${JVMS[OPTION]##*/}" - # Disable all jdk - for (( i = 0; i < ${#JVMS[@]}; i++ )); do - if [[ -f "${JVMS_DIR}/${JVMS[$i]}/Contents/Info.plist" ]]; then - sudo mv "${JVMS_DIR}/${JVMS[$i]}/Contents/Info.plist" "${JVMS_DIR}/${JVMS[$i]}/Contents/Info.plist.disable" - fi - done + # Disable all jdk + for ((i = 0; i < ${#JVMS[@]}; i++)); do + if [[ "${JVMS[i]}" != "${DEFAULT_JVM_DIR}" && -f "${JVMS[i]}/Contents/Info.plist" ]]; then + sudo mv "${JVMS[i]}/Contents/Info.plist" "${JVMS[i]}/Contents/Info.plist.disable" + fi + done - # Enable default jdk - if [[ -f "${DEFAULT_JVM_DIR}/Contents/Info.plist.disable" ]]; then - sudo mv "${DEFAULT_JVM_DIR}/Contents/Info.plist.disable" "${DEFAULT_JVM_DIR}/Contents/Info.plist" - echo "Enabled ${DEFAULT_JVM} as default JVM" - fi + # Enable default jdk + if [[ -f "${DEFAULT_JVM_DIR}/Contents/Info.plist.disable" ]]; then + sudo mv -vn "${DEFAULT_JVM_DIR}/Contents/Info.plist.disable" "${DEFAULT_JVM_DIR}/Contents/Info.plist" \ + && echo "Enabled ${DEFAULT_JVM} as default JVM" + fi } - -# Make this backwards compatible -alias pcurl='prevcurl' From db9027989d473ec4dfc4e226e98f5f6c21be0b1d Mon Sep 17 00:00:00 2001 From: John D Pell Date: Thu, 30 Dec 2021 12:09:20 -0800 Subject: [PATCH 3/6] plugin/osx: remove `dock-switch()` ...it hasn't worked in *years* --- plugins/available/osx.plugin.bash | 32 ------------------------------- 1 file changed, 32 deletions(-) diff --git a/plugins/available/osx.plugin.bash b/plugins/available/osx.plugin.bash index 555de8a3..532717a7 100644 --- a/plugins/available/osx.plugin.bash +++ b/plugins/available/osx.plugin.bash @@ -31,38 +31,6 @@ function winname { printf '%b' "\e]2;$1\a" } -# this one switches your os x dock between 2d and 3d -# thanks to savier.zwetschge.org -function dock-switch() { - about 'switch dock between 2d and 3d' - param '1: "2d" or "3d"' - example '$ dock-switch 2d' - group 'osx' - - case $OSTYPE in - *'darwin'*) - case $1 in - 3d) - defaults write com.apple.dock no-glass -boolean NO - killall Dock - ;; - 2d) - defaults write com.apple.dock no-glass -boolean YES - killall Dock - ;; - *) - echo "usage:" - echo "dock-switch 2d" - echo "dock-switch 3d." - ;; - esac - ;; - *) - echo "Sorry, this only works on Mac OS X" - ;; - esac -} - function pman() { about 'view man documentation in Preview' param '1: man page to view' From caa0d48c6058037181fc895369d998e723ef142b Mon Sep 17 00:00:00 2001 From: John D Pell Date: Thu, 30 Dec 2021 12:16:37 -0800 Subject: [PATCH 4/6] plugin/osx: move `$OSTYPE` check to top of file --- plugins/available/osx.plugin.bash | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/plugins/available/osx.plugin.bash b/plugins/available/osx.plugin.bash index 532717a7..139f58a1 100644 --- a/plugins/available/osx.plugin.bash +++ b/plugins/available/osx.plugin.bash @@ -1,6 +1,11 @@ # shellcheck shell=bash about-plugin 'osx-specific functions' +if [[ "${OSTYPE}" != 'darwin'* ]]; then + _log_warning "This plugin only works with Mac OS X." + return 1 +fi + # OS X: Open new tabs in same directory if _is_function update_terminal_cwd; then safe_append_prompt_command 'update_terminal_cwd' @@ -53,10 +58,6 @@ function prevcurl() { param '1: url' group 'osx' - if [[ ! $OSTYPE = 'darwin'* ]]; then - echo "This function only works with Mac OS X" - return 1 - fi curl "$*" | open -fa 'Preview' } @@ -65,12 +66,8 @@ function refresh-launchpad() { example '$ refresh-launchpad' group 'osx' - if [[ "$OSTYPE" = 'darwin'* ]]; then - defaults write com.apple.dock ResetLaunchPad -bool TRUE - killall Dock - else - echo "Sorry, this only works on Mac OS X" - fi + defaults write com.apple.dock ResetLaunchPad -bool TRUE + killall Dock } function list-jvms() { From 03653fc1418648c318e60b706a8abcae1df0cbe5 Mon Sep 17 00:00:00 2001 From: John D Pell Date: Mon, 26 Jul 2021 02:02:01 -0700 Subject: [PATCH 5/6] plugins/osx-timemachine: `shellcheck` && `shfmt` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use bash functionality rather than external binaries. Alsö, if $SUDO_ASKPASS is set then pass -A to sudo. --- clean_files.txt | 1 + plugins/available/osx-timemachine.plugin.bash | 114 ++++++++++-------- 2 files changed, 63 insertions(+), 52 deletions(-) diff --git a/clean_files.txt b/clean_files.txt index a70a44c2..069d7ae5 100644 --- a/clean_files.txt +++ b/clean_files.txt @@ -103,6 +103,7 @@ plugins/available/jump.plugin.bash plugins/available/less-pretty-cat.plugin.bash plugins/available/node.plugin.bash plugins/available/nodenv.plugin.bash +plugins/available/osx-timemachine.plugin.bash plugins/available/osx.plugin.bash plugins/available/percol.plugin.bash plugins/available/plenv.plugin.bash diff --git a/plugins/available/osx-timemachine.plugin.bash b/plugins/available/osx-timemachine.plugin.bash index 3d7ff00c..2eef14bd 100644 --- a/plugins/available/osx-timemachine.plugin.bash +++ b/plugins/available/osx-timemachine.plugin.bash @@ -1,84 +1,94 @@ -cite about-plugin +# shellcheck shell=bash about-plugin 'OS X Time Machine functions' -function time-machine-destination() { - group "osx-timemachine" - about "Shows the OS X Time Machine destination/mount point" +if [[ "${OSTYPE}" != 'darwin'* ]]; then + _log_warning "This plugin only works with Mac OS X" + return 1 +fi - echo $(tmutil destinationinfo | grep "Mount Point" | sed -e 's/Mount Point : \(.*\)/\1/g') +function time-machine-destination() { + group "osx-timemachine" + about "Shows the OS X Time Machine destination/mount point" + + tmutil destinationinfo | grep "Mount Point" | sed -e 's/Mount Point : \(.*\)/\1/g' } function time-machine-list-machines() { - group "osx-timemachine" - about "Lists the OS X Time Machine machines on the backup volume" + group "osx-timemachine" + about "Lists the OS X Time Machine machines on the backup volume" - local tmdest="$(time-machine-destination)/Backups.backupdb" + local tmdest + tmdest="$(time-machine-destination)/Backups.backupdb" - find "$tmdest" -maxdepth 1 -mindepth 1 -type d | grep -v "/\." | while read line ; do - echo "${line##*/}" - done + find "$tmdest" -maxdepth 1 -mindepth 1 -type d | grep -v "/\." | while read -r line; do + echo "${line##*/}" + done } function time-machine-list-all-backups() { - group "osx-timemachine" - about "Shows all of the backups for the specified machine" - param "1: Machine name (optional)" - example "time-machine-list-all-backups my-laptop" + group "osx-timemachine" + about "Shows all of the backups for the specified machine" + param "1: Machine name (optional)" + example "time-machine-list-all-backups my-laptop" - # Use the local hostname if none provided - local COMPUTERNAME=${1:-$(scutil --get ComputerName)} - local BACKUP_LOCATION="$(time-machine-destination)/Backups.backupdb/$COMPUTERNAME" + # Use the local hostname if none provided + local COMPUTERNAME BACKUP_LOCATION + COMPUTERNAME=${1:-$(scutil --get ComputerName)} + BACKUP_LOCATION="$(time-machine-destination)/Backups.backupdb/$COMPUTERNAME" - find "$BACKUP_LOCATION" -maxdepth 1 -mindepth 1 -type d | while read line ; do - echo "$line" - done + find "$BACKUP_LOCATION" -maxdepth 1 -mindepth 1 -type d | while read -r line; do + echo "$line" + done } function time-machine-list-old-backups() { - group "osx-timemachine" - about "Shows all of the backups for the specified machine, except for the most recent backup" - param "1: Machine name (optional)" - example "time-machine-list-old-backups my-laptop" + group "osx-timemachine" + about "Shows all of the backups for the specified machine, except for the most recent backup" + param "1: Machine name (optional)" + example "time-machine-list-old-backups my-laptop" - # Use the local hostname if none provided - local COMPUTERNAME=${1:-$(scutil --get ComputerName)} - local BACKUP_LOCATION="$(time-machine-destination)/Backups.backupdb/$COMPUTERNAME" + # Use the local hostname if none provided + local COMPUTERNAME BACKUP_LOCATION + COMPUTERNAME=${1:-$(scutil --get ComputerName)} + BACKUP_LOCATION="$(time-machine-destination)/Backups.backupdb/$COMPUTERNAME" - # List all but the most recent one - find "$BACKUP_LOCATION" -maxdepth 1 -mindepth 1 -type d -name 2\* | sed \$d | while read line ; do - echo "$line" - done + # List all but the most recent one + find "$BACKUP_LOCATION" -maxdepth 1 -mindepth 1 -type d -name 2\* | sed \$d | while read -r line; do + echo "$line" + done } # Taken from here: http://stackoverflow.com/a/30547074/1228454 function _tm_startsudo() { - sudo -v - ( while true; do sudo -v; sleep 50; done; ) & - SUDO_PID="$!" - trap _tm_stopsudo SIGINT SIGTERM + sudo -v # validate without running a command. + (while sudo "-${SUDO_ASKPASS:+A}v"; do + sleep 50 + done) & + SUDO_PID="$!" + trap _tm_stopsudo SIGINT SIGTERM } function _tm_stopsudo() { - kill "$SUDO_PID" - trap - SIGINT SIGTERM - sudo -k + kill "$SUDO_PID" + trap - SIGINT SIGTERM + sudo -k } function time-machine-delete-old-backups() { - group "osx-timemachine" - about "Deletes all of the backups for the specified machine, with the exception of the most recent one" - param "1: Machine name (optional)" - example "time-machine-delete-old-backups my-laptop" + group "osx-timemachine" + about "Deletes all of the backups for the specified machine, with the exception of the most recent one" + param "1: Machine name (optional)" + example "time-machine-delete-old-backups my-laptop" - # Use the local hostname if none provided - local COMPUTERNAME=${1:-$(scutil --get ComputerName)} + # Use the local hostname if none provided + local COMPUTERNAME=${1:-$(scutil --get ComputerName)} _old_backup - # Ask for sudo credentials only once - _tm_startsudo + # Ask for sudo credentials only once + _tm_startsudo - echo "$(time-machine-list-old-backups "$COMPUTERNAME")" | while read i ; do - # Delete the backup - sudo tmutil delete "$i" - done + while read -r _old_backup; do + # Delete the backup + sudo tmutil delete "$_old_backup" + done <<< "$(time-machine-list-old-backups "$COMPUTERNAME")" - _tm_stopsudo + _tm_stopsudo } From 45aeb86c219d121f0fdd819040c17e277e1fb93a Mon Sep 17 00:00:00 2001 From: John D Pell Date: Thu, 30 Dec 2021 12:38:52 -0800 Subject: [PATCH 6/6] plugin/osx-timemachine: abuse `$SUDO_COMMAND` Use `$SUDO_COMMAND` as a back-channel to `ssh-askpass` to set a reasonable title if it pops up. --- plugins/available/osx-timemachine.plugin.bash | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/available/osx-timemachine.plugin.bash b/plugins/available/osx-timemachine.plugin.bash index 2eef14bd..e30d37bd 100644 --- a/plugins/available/osx-timemachine.plugin.bash +++ b/plugins/available/osx-timemachine.plugin.bash @@ -60,7 +60,8 @@ function time-machine-list-old-backups() { # Taken from here: http://stackoverflow.com/a/30547074/1228454 function _tm_startsudo() { - sudo -v # validate without running a command. + local -x SUDO_COMMAND="plugin/osx-timemachine: keep 'sudo' token alive during long-run 'tmutil' commands" + sudo "-${SUDO_ASKPASS:+A}v" # validate without running a command, using `ssh-askpass` if available. (while sudo "-${SUDO_ASKPASS:+A}v"; do sleep 50 done) &