├── .github └── stale.yml ├── .gitignore ├── LICENSE.md ├── README.md ├── images ├── demo.gif ├── sponsor-download-badge.png └── sponsor-icon.png ├── mac └── mac-cli ├── completion ├── bash_completion └── fish_completion ├── misc └── help ├── plugins ├── brew ├── dns ├── general ├── git ├── network ├── performance ├── search ├── ssh └── volume └── tools ├── install ├── uninstall └── update /.github/stale.yml: -------------------------------------------------------------------------------- 1 | # Number of days of inactivity before an issue becomes stale 2 | daysUntilStale: 60 3 | # Number of days of inactivity before a stale issue is closed 4 | daysUntilClose: 7 5 | # Issues with these labels will never be considered stale 6 | exemptLabels: 7 | - pinned 8 | - security 9 | # Label to use when marking an issue as stale 10 | staleLabel: wontfix 11 | # Comment to post when marking an issue as stale. Set to `false` to disable 12 | markComment: > 13 | This issue has been automatically marked as stale because it has not had 14 | recent activity. It will be closed if no further activity occurs. Thank you 15 | for your contributions. 16 | # Comment to post when closing a stale issue. Set to `false` to disable 17 | closeComment: false 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea/ 3 | .idea/workspace.xml 4 | .phpstorm.meta.php 5 | *.iml -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015-2022 Gabriel Guarino 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Mac CLI 2 | 3 |  macOS command line tools for developers 4 | 5 | 6 | --- 7 | 8 | ### Sponsors 9 | 10 | >[![Sponsor logo](images/sponsor-icon.png)](https://apps.apple.com/us/app/superplanner/id6443725564) 11 | > 12 | >Mac CLI is sponsored by 📒 [SuperPlanner](https://superplanner.app/), an innovative daily planner and task manager for iPhone, iPad and Mac. 13 | > 14 | >SuperPlanner combines the calendar with task management features to keep everything organized in one place. 15 | > 16 | >There is no login or user registration required. All data is stored locally and syncs between your devices using private and secure iCloud sync. 17 | > 18 | >[![Sponsor download badge](images/sponsor-download-badge.png)](https://apps.apple.com/us/app/superplanner/id6443725564) 19 | 20 | --- 21 | 22 | ### Introduction 23 | 24 | Mac CLI is the ultimate tool for developers to manage their Mac. It provides a huge set of command line commands that automate the usage of your macOS system. 25 | When you run a function, the executed command is displayed and that helps you memorize each of the Utilities for future usage. 26 | 27 | The tool is designed to be easily extendable with additional commands through the use of plugins. To view the currently available commands, you can navigate to the plugins folder and explore the different categories: [/mac-cli/plugins](https://github.com/guarinogabriel/mac-cli/tree/master/mac-cli/plugins) 28 | 29 | _Contributions to add new plugins and keep improving the existing ones are welcome and very much appreciated!_ 30 | 31 | ![image](images/demo.gif) 32 | 33 | --- 34 | 35 | ### Installation in 1 Simple Step - Including Configuration Wizard! 36 | 37 | Via curl 38 | > `sh -c "$(curl -fsSL https://raw.githubusercontent.com/guarinogabriel/mac-cli/master/mac-cli/tools/install)"` 39 | 40 | Via wget 41 | > `sh -c "$(wget https://raw.githubusercontent.com/guarinogabriel/mac-cli/master/mac-cli/tools/install -O -)"` 42 | 43 | Then, re-open your terminal client. You will be able to run all the commands listed below, for example: 44 | > `mac help` 45 | 46 | --- 47 | 48 | ### Configuration 49 | 50 | The configuration is done when you install Mac CLI for the first time though the installer configuration wizard. 51 | After that, you can update your Mac CLI configuration by editing the following file: `/usr/local/bin/mac` 52 | 53 | --- 54 | 55 | ### Requirements 56 | 57 | These are the requirements to be able to run all the commands (the dependencies/requirements are installed when you install Mac CLI for the first time): 58 | 59 | * Homebrew 60 | * Git 61 | * Pipe Viewer (pv) 62 | 63 | --- 64 | 65 | ### Update 66 | 67 | You can update Mac CLI to the latest version by running: 68 | > `sh -c "$(curl -fsSL https://raw.githubusercontent.com/guarinogabriel/mac-cli/master/mac-cli/tools/update)"` 69 | 70 | --- 71 | 72 | ### Uninstallation 73 | 74 | You can uninstall Mac CLI by running: 75 | > `sh -c "$(curl -fsSL https://raw.githubusercontent.com/guarinogabriel/mac-cli/master/mac-cli/tools/uninstall)"` 76 | 77 | --- 78 | 79 | ### Help / Commands List 80 | 81 | | Command | Description | Arguments | 82 | | ------------- | ------------- | ------------- | 83 | | `mac help` | List all available commands in mac script | | 84 | 85 | ### General Commands 86 | 87 | | Command | Description | Arguments | 88 | | ------------- | ------------- | ------------- | 89 | | `mac update` | Install macOS software updates, update installed Ruby gems, Homebrew, npm and their installed packages | | 90 | | `mac lock` | Lock | | 91 | | `mac restart` | Restart macOS | | 92 | | `mac sleep` | Sleep mode | | 93 | | `mac shutdown` | Shutdown | | 94 | | `mac time` | Show clock at top right position in Terminal/iTerm | | 95 | | `mac screensaver` | Start screensaver | | 96 | | `mac folders:list` | List folders in current directory with their current size | | 97 | | `mac folder:size` | Calculate current folder size | | 98 | | `mac bluetooth:status` | Get the bluetooth status | | 99 | | `mac bluetooth:enable` | Enable bluetooth | | 100 | | `mac bluetooth:disable` | Disable bluetooth | | 101 | | `mac wifi:status` | Get the wifi status | | 102 | | `mac wifi:scan` | Scan available wifi networks | | 103 | | `mac wifi:enable` | Enable wifi | | 104 | | `mac wifi:disable` | Disable wifi | | 105 | | `mac dock:add-space N` | Add blank space to dock | N = number of spaces | 106 | | `mac eject-all` | Eject all mounted volumes and disks | | 107 | | `mac battery` | Get battery status | | 108 | | `mac info` | Get macOS version information | | 109 | | `mac hidden:show` | Show hidden files | | 110 | | `mac hidden:hide` | Hide hidden files | | 111 | | `mac find:text X` | Find exact phrase recursively inside directory | X = Text string | 112 | | `mac find:biggest-files` | Find biggest files inside directory | | 113 | | `mac find:biggest-directories` | Find biggest directories inside directory | | 114 | | `mac zip:extract X` | Extract Zip file to current folder | X = Zip file to extract | 115 | | `mac gzip:compress X` | Compress current file using Gzip | X = File to compress | 116 | | `mac gzip:extract X` | Extract Gzip file to current folder | X = Gzip file to extract | 117 | | `mac tar:compress X` | Compress X file/directory using tar with progress indicator | X = File or directory | 118 | | `mac tar:extract X` | Extract tar file to current folder | X = Tar file to extract | 119 | 120 | 121 | ### Search Utilities 122 | 123 | | Command | Description | Arguments | 124 | | ------------- | ------------- | ------------- | 125 | | `mac find:recent N` | Find files modified in the last N minutes | N = number of minutes | 126 | | `mac search:replace X` | Search and replace string in file | X = File to perform the search and replace operation | 127 | 128 | 129 | ### Network Utilities 130 | 131 | | Command | Description | 132 | | ------------- | ------------- | 133 | | `mac speedtest` | Internet connection speed test | 134 | | `mac ports` | List of used ports | 135 | | `mac ip:local` | Get local IP address | 136 | | `mac ip:public` | Get public IP address | 137 | 138 | 139 | ### DNS Utilities 140 | 141 | | Command | Description | 142 | | ------------- | ------------- | 143 | | `mac dns:list` | List DNS server(s) | 144 | | `mac dns:add` | Add DNS server | 145 | | `mac dns:remove` | Remove DNS server | 146 | | `mac dns:flush` | Flush DNS cache | 147 | 148 | 149 | ### SSH Utilities 150 | 151 | | Command | Description | Arguments | 152 | | ------------- | ------------- | ------------- | 153 | | `mac ssh:download-file X` | Download file from remote server through SSH | X = Path of the remote file to download | 154 | | `mac ssh:download-folder X` | Download entire folder from remote server through SSH | X = Path of the remote folder to download | 155 | | `mac ssh:sync:local X` | Sync local folder with remote folder using rsync through SSH (download remote folder to local folder) | X = Path of the remote folder to sync to local folder | 156 | | `mac ssh:sync:remote X` | Sync remote folder with local folder using rsync through SSH (upload local folder to remote folder) | X = Path of the remote folder to sync from local folder | 157 | | `mac ssh:upload X` | Upload file to remote server through SSH | X = Path of the file to upload to the remote server | 158 | | `mac ssh:public-key` | Copy SSH Public Key | | 159 | | `mac ssh:list` | List all the saved SSH credentials | | 160 | 161 | 162 | ### Performance and maintenance Utilities 163 | 164 | | Command | Description | 165 | | ------------- | ------------- | 166 | | `mac system` | Show system information to review mac performance | 167 | | `mac temp` | Show temperature, fan and battery statistics | 168 | | `mac memory` | See memory usage sorted by memory consumption | 169 | | `mac trash:empty` | Empty trash | 170 | | `mac trash:size` | Calculate trash size | 171 | 172 | 173 | ### Git Utilities 174 | 175 | | Command | Description | 176 | | ------------- | ------------- | 177 | | `mac git:config` | Display local Git configuration | 178 | | `mac git:open` | Open current repository on Github | 179 | | `mac git:create:branch` | Create branch based on current branch | 180 | | `mac git:branches:date` | Get last update date for all branches in current project | 181 | | `mac git:undo-commit` | Undo latest commit | 182 | | `mac git:log` | See latest commits IDs and titles for current branch | 183 | | `mac git:branch` | See all branches | 184 | | `mac git:branch:rename` | Rename Git branch | 185 | | `mac git:branch:remove-local` | Remove local Git branch | 186 | | `mac git:branch:remove-remote` | Remove local and remote Git branch | 187 | | `mac git:settings` | Check Git settings | 188 | | `mac git:add-removed` | Add removed files to staged files | 189 | | `mac git:size` | Get size for current Git directory | 190 | 191 | ### Homebrew Utilities 192 | 193 | | Command | Description | 194 | | ------------- | ------------- | 195 | | `mac brew` | Get a list of installed Homebrew packages | 196 | -------------------------------------------------------------------------------- /images/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guarinogabriel/Mac-CLI/ff32f1c64dfc9b21c5b6304d8d02e28ceccdb39a/images/demo.gif -------------------------------------------------------------------------------- /images/sponsor-download-badge.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guarinogabriel/Mac-CLI/ff32f1c64dfc9b21c5b6304d8d02e28ceccdb39a/images/sponsor-download-badge.png -------------------------------------------------------------------------------- /images/sponsor-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/guarinogabriel/Mac-CLI/ff32f1c64dfc9b21c5b6304d8d02e28ceccdb39a/images/sponsor-icon.png -------------------------------------------------------------------------------- /mac: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | ########################################################################### 3 | #  mac CLI (mac command line tools) - macOS command line tools for developers 4 | ########################################################################### 5 | 6 | # Version: 2.0 7 | # Date: December 8, 2015 8 | # Author: Gabriel Guarino 9 | # 10 | # Collection of useful functions to automate macOS common tasks 11 | # 12 | ########################################################################### 13 | 14 | # Mac CLI directory 15 | MAC="$(dirname "$0")" 16 | 17 | #-------------------------------------------------------------------- 18 | # Configuration 19 | #-------------------------------------------------------------------- 20 | export echocommand="true" 21 | 22 | #-------------------------------------------------------------------- 23 | # Parameters 24 | #-------------------------------------------------------------------- 25 | export fn=$1 26 | export firstParameter=$2 27 | export secondParameter=$3 28 | export allParameters=${@:2} 29 | 30 | #-------------------------------------------------------------------- 31 | # Colors 32 | #-------------------------------------------------------------------- 33 | export GREEN='\033[0;32m' 34 | export GRAY='\033[0;37m' 35 | export LIGHTBLUE='\033[1;34m' 36 | export LIGHTGREEN='\033[1;32m' 37 | export WHITEBOLD='\033[1;37m' 38 | export RED='\033[1;31m' 39 | export NC='\033[0m' # No Color 40 | 41 | #-------------------------------------------------------------------- 42 | # List of Commands 43 | #-------------------------------------------------------------------- 44 | 45 | COMMANDS=( 46 | list 47 | help 48 | usage 49 | categories 50 | general 51 | search 52 | network 53 | dns 54 | ssh 55 | webdev 56 | performance 57 | terminal 58 | git 59 | web_utilities 60 | homebrew 61 | image 62 | magento 63 | update 64 | upgrade 65 | uninstall 66 | lock 67 | restart 68 | sleep 69 | display 70 | shutdown 71 | uptime 72 | volume 73 | volume:ismute 74 | volume:mute 75 | volume:unmute 76 | hidden:show 77 | hidden:hide 78 | screensaver 79 | folders:list 80 | folder:size 81 | dock:add-space 82 | bluetooth:status 83 | bluetooth:enable 84 | bluetooth:disable 85 | wifi:status 86 | wifi:scan 87 | wifi:enable 88 | wifi:disable 89 | eject-all 90 | battery 91 | info 92 | find:text 93 | find:biggest-files 94 | find:biggest-directories 95 | zip:extract 96 | gzip:compress 97 | gzip:extract 98 | tar:compress 99 | tar:extract 100 | find:recent 101 | search:replace 102 | speedtest 103 | ports 104 | ip:local 105 | ip:public 106 | dns:list 107 | dns:add 108 | dns:remove 109 | dns:flush 110 | hosts:edit 111 | ssh:download-file 112 | ssh:download-folder 113 | ssh:sync:local 114 | ssh:sync:remote 115 | ssh:upload 116 | ssh:public-key 117 | ssh:list 118 | system 119 | temp 120 | memory 121 | trash:empty 122 | trash:size 123 | git:config 124 | git:open 125 | git:create:branch 126 | git:branches:date 127 | git:undo-commit 128 | git:log 129 | git:branch 130 | git:branch:rename 131 | git:branch:remove-local 132 | git:branch:remove-remote 133 | git:branch 134 | git:settings 135 | git:add-removed 136 | git:size 137 | brew:update 138 | ) 139 | ## ---- END OF COMMANDS; Comment required for bash_completion------ 140 | 141 | if [ -z "$fn" ] || [[ "$#" -lt "1" ]]; then 142 | fn="list" 143 | fi 144 | 145 | #-------------------------------------------------------------------- 146 | # Help 147 | #-------------------------------------------------------------------- 148 | 149 | # Documentation / Help 150 | source "$MAC/mac-cli/misc/help" 151 | 152 | #-------------------------------------------------------------------- 153 | # Catch command not found 154 | #-------------------------------------------------------------------- 155 | 156 | if [[ ! " ${COMMANDS[@]} " =~ " ${fn} " ]]; then 157 | echo "${RED}Command not found: '${fn}' $(test ! -z "$allParameters" -a "$allParameters" != " " && echo "\nParameters: $allParameters" || echo "")${NC}" 158 | read -p "Choose a category for which to list help/usage... ($(categoriesList)) " category # Ask user for a category to print usage 159 | 160 | if [ ! -z "${category}" ]; then 161 | echo "$(usageList ${category})\n" # Show help/usage for user-selected category 162 | echo "$(printAdditionalHelp)" 163 | else 164 | kill -INT $$ # Exit 165 | fi 166 | fi 167 | 168 | #-------------------------------------------------------------------- 169 | # Plugins 170 | #-------------------------------------------------------------------- 171 | 172 | source "$MAC/mac-cli/plugins/brew" 173 | source "$MAC/mac-cli/plugins/general" 174 | source "$MAC/mac-cli/plugins/git" 175 | source "$MAC/mac-cli/plugins/network" 176 | source "$MAC/mac-cli/plugins/dns" 177 | source "$MAC/mac-cli/plugins/performance" 178 | source "$MAC/mac-cli/plugins/search" 179 | source "$MAC/mac-cli/plugins/ssh" 180 | source "$MAC/mac-cli/plugins/volume" 181 | -------------------------------------------------------------------------------- /mac-cli/completion/bash_completion: -------------------------------------------------------------------------------- 1 | # Mac_CLI bash completion 2 | 3 | have mac && { 4 | _mac() { 5 | local MACWORDS cur 6 | 7 | COMPREPLY=() 8 | _get_comp_words_by_ref -n : cur 9 | 10 | MACWORDS=$(awk "/COMMANDS=/,/#/" < /usr/local/bin/mac | tail -n +2 | sed '/)/d;/#/d') 11 | 12 | COMPREPLY=( $( compgen -W "$MACWORDS" -- "$cur" ) ) 13 | 14 | __ltrim_colon_completions "$cur" 15 | } 16 | complete -F _mac mac 17 | } -------------------------------------------------------------------------------- /mac-cli/completion/fish_completion: -------------------------------------------------------------------------------- 1 | complete -c mac -a (awk "/COMMANDS=/,/#/" < /usr/local/bin/mac | tail -n +2 | sed '/)/d;/#/d' | tr -d '\n') 2 | -------------------------------------------------------------------------------- /mac-cli/misc/help: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | #-------------------------------------------------------------------- 4 | # mac script commands list - all commands 5 | #-------------------------------------------------------------------- 6 | 7 | MacCategories=( 8 | general 9 | git 10 | homebrew 11 | lamp 12 | network 13 | dns 14 | performance 15 | search 16 | ssh 17 | terminal 18 | web_utilities 19 | webdev 20 | ) 21 | 22 | function printInfo() 23 | { 24 | echo "\n${WHITEBOLD} mac CLI – OS X command line tools for developers" 25 | echo "====================================================${NC}" 26 | } 27 | 28 | function printAdditionalHelp() 29 | { 30 | echo "\nRun ${LIGHTBLUE}mac help${NC} for full usage, ${LIGHTBLUE}mac categories${NC} for categories list, or ${LIGHTBLUE}mac {category}${NC} for usage related to {category}" 31 | echo "${NC}\n" 32 | } 33 | 34 | function categoriesList() 35 | { 36 | cats=${cats}$(printf "%s|" "${MacCategories[@]}") 37 | cats="${cats%?}" 38 | echo "${cats}" 39 | } 40 | 41 | function usageList() 42 | { 43 | case ${1} in 44 | general) 45 | echo "\n${WHITEBOLD}General Utilities: " 46 | echo "${LIGHTBLUE}mac update${GRAY}: Install OS X software updates, update installed Ruby gems, Homebrew, npm and their installed packages" 47 | echo "${LIGHTBLUE}mac upgrade${GRAY}: Upgrade Mac CLI to the latest version" 48 | echo "${LIGHTBLUE}mac uninstall${GRAY}: Uninstall Mac CLI" 49 | echo "${LIGHTBLUE}mac lock${GRAY}: Lock" 50 | echo "${LIGHTBLUE}mac restart${GRAY}: Restart OS X" 51 | echo "${LIGHTBLUE}mac sleep${GRAY}: Sleep mode" 52 | echo "${LIGHTBLUE}mac shutdown${GRAY}: Shutdown" 53 | echo "${LIGHTBLUE}mac uptime${GRAY}: Get the time since last restart" 54 | echo "${LIGHTBLUE}mac volume${GRAY}: Get the volume from the terminal" 55 | echo "${LIGHTBLUE}mac volume ${LIGHTGREEN}X${GRAY}: Set the volume from the terminal - ${LIGHTGREEN}X = Level (0-100)" 56 | echo "${LIGHTBLUE}mac volume:mute${GRAY}: Mute volume" 57 | echo "${LIGHTBLUE}mac volume:unmute${GRAY}: Unmute volume" 58 | echo "${LIGHTBLUE}mac volume:ismute${GRAY}: Check if the volume is muted or not" 59 | echo "${LIGHTBLUE}mac screensaver${GRAY}: Start screensaver" 60 | echo "${LIGHTBLUE}mac folders:list${GRAY}: List folders in current directory with their current size" 61 | echo "${LIGHTBLUE}mac folder:size${GRAY}: Calculate current folder size" 62 | echo "${LIGHTBLUE}mac dock:add-space ${LIGHTGREEN}N${GRAY}: Add blank space to dock - ${LIGHTGREEN}N = Number of spaces to add" 63 | echo "${LIGHTBLUE}mac eject-all${GRAY}: Eject all mounted volumes and disks" 64 | echo "${LIGHTBLUE}mac battery${GRAY}: Get battery information" 65 | echo "${LIGHTBLUE}mac info${GRAY}: Get OS X version information" 66 | echo "${LIGHTBLUE}mac find:text ${LIGHTGREEN}X${GRAY}: Find exact phrase recursively inside directory - ${LIGHTGREEN}X = Text string" 67 | echo "${LIGHTBLUE}mac find:biggest-files ${GRAY}: Find biggest files inside directory" 68 | echo "${LIGHTBLUE}mac find:biggest-directories ${GRAY}: Find biggest directories inside directory" 69 | echo "${LIGHTBLUE}mac zip:extract ${LIGHTGREEN}X${GRAY}: Extract Zip file to current folder - ${LIGHTGREEN}X = Zip file to extract" 70 | echo "${LIGHTBLUE}mac gzip:compress ${LIGHTGREEN}X${GRAY}: Compress current file using Gzip - ${LIGHTGREEN}X = File to compress" 71 | echo "${LIGHTBLUE}mac gzip:extract ${LIGHTGREEN}X${GRAY}: Extract Gzip file to current folder - ${LIGHTGREEN}X = Gzip file to extract" 72 | echo "${LIGHTBLUE}mac tar:compress ${LIGHTGREEN}X${GRAY}: Compress X file/directory using tar with progress indicator - ${LIGHTGREEN}X = File or directory" 73 | echo "${LIGHTBLUE}mac tar:extract ${LIGHTGREEN}X${GRAY}: Extract tar file to current folder - ${LIGHTGREEN}X = Tar file to extract" 74 | echo "${NC}\n" 75 | ;; 76 | search) 77 | echo "\n${WHITEBOLD}Search Utilities: " 78 | echo "${LIGHTBLUE}mac find:recent ${LIGHTGREEN}X${GRAY}: Find files modified in the last N minutes - ${LIGHTGREEN}X = number of minutes " 79 | echo "${LIGHTBLUE}mac search:replace ${LIGHTGREEN}X${GRAY}: Search and replace string in file - ${LIGHTGREEN}X = File to perform the search and replace operation" 80 | echo "${NC}\n" 81 | ;; 82 | network) 83 | echo "\n${WHITEBOLD}Network Utilities: " 84 | echo "${LIGHTBLUE}mac speedtest${GRAY}: Internet connection speed test " 85 | echo "${LIGHTBLUE}mac ports${GRAY}: List of used ports " 86 | echo "${LIGHTBLUE}mac ip:local${GRAY}: Get local IP address " 87 | echo "${LIGHTBLUE}mac ip:public${GRAY}: Get public IP address " 88 | echo "${NC}\n" 89 | ;; 90 | dns) 91 | echo "\n${WHITEBOLD}DNS Utilities: " 92 | echo "${LIGHTBLUE}mac dns:list${GRAY}: List DNS server(s) " 93 | echo "${LIGHTBLUE}mac dns:add${GRAY}: Add DNS server " 94 | echo "${LIGHTBLUE}mac dns:remove${GRAY}: Remove DNS server " 95 | echo "${LIGHTBLUE}mac dns:flush${GRAY}: Flush DNS cache " 96 | echo "${NC}\n" 97 | ;; 98 | ssh) 99 | echo "\n${WHITEBOLD}SSH Utilities: " 100 | echo "${LIGHTBLUE}mac ssh:download-file ${LIGHTGREEN}X${GRAY}: Download file from remote server through SSH - X = Path of the remote file to download " 101 | echo "${LIGHTBLUE}mac ssh:download-folder ${LIGHTGREEN}X${GRAY}: Download entire folder from remote server through SSH - X = Path of the remote folder to download " 102 | echo "${LIGHTBLUE}mac ssh:sync:local ${LIGHTGREEN}X${GRAY}: Sync local folder with remote folder using rsync through SSH (download remote folder to local folder)" 103 | echo "${LIGHTBLUE}mac ssh:sync:remote ${LIGHTGREEN}X${GRAY}: Path of the remote folder to sync from local folder (upload local folder to remote folder) " 104 | echo "${LIGHTBLUE}mac ssh:upload ${LIGHTGREEN}X${GRAY}: Upload file to remote server through SSH - X = Path of the file to upload to the remote server " 105 | echo "${LIGHTBLUE}mac ssh:public-key ${LIGHTGREEN}X${GRAY}: Get public SSH key for local machine " 106 | echo "${NC}\n" 107 | ;; 108 | performance) 109 | echo "\n${WHITEBOLD}Performance and maintenance Utilities: " 110 | echo "${LIGHTBLUE}mac system${GRAY}: Show system information to review mac performance " 111 | echo "${LIGHTBLUE}mac temp${GRAY}: Show temperature, fan and battery statistics " 112 | echo "${LIGHTBLUE}mac memory${GRAY}: See memory usage sorted by memory consumption " 113 | echo "${LIGHTBLUE}mac trash:empty${GRAY}: Empty trash" 114 | echo "${LIGHTBLUE}mac trash:size${GRAY}: Calculate trash size" 115 | echo "${NC}\n" 116 | ;; 117 | git) 118 | echo "\n${WHITEBOLD}Git Utilities: " 119 | echo "${LIGHTBLUE}mac git:config${GRAY}: Display local Git configuration " 120 | echo "${LIGHTBLUE}mac git:open${GRAY}: Open current repository on Github " 121 | echo "${LIGHTBLUE}mac git:create:branch${GRAY}: Create branch based on current branch " 122 | echo "${LIGHTBLUE}mac git:branches:date${GRAY}: Get last update date for all branches in current project " 123 | echo "${LIGHTBLUE}mac git:undo-commit${GRAY}: Undo latest commit " 124 | echo "${LIGHTBLUE}mac git:log${GRAY}: See latest commits IDs and titles for current branch " 125 | echo "${LIGHTBLUE}mac git:branch${GRAY}: See all branches " 126 | echo "${LIGHTBLUE}mac git:branch:rename${GRAY}: Rename Git branch " 127 | echo "${LIGHTBLUE}mac git:branch:remove-local${GRAY}: Remove local Git branch " 128 | echo "${LIGHTBLUE}mac git:branch:remove-remote${GRAY}: Remove local and remote Git branch " 129 | echo "${LIGHTBLUE}mac git:branch${GRAY}: See all branches " 130 | echo "${LIGHTBLUE}mac git:add-removed${GRAY}: Add removed files to staged files " 131 | echo "${LIGHTBLUE}mac git:size${GRAY}: Get size for current Git repository " 132 | echo "${NC}\n" 133 | ;; 134 | homebrew) 135 | echo "\n${WHITEBOLD}Homebrew Utilities: " 136 | echo "${LIGHTBLUE}mac brew:update${GRAY}: Upgrade Homebrew, installed Homebrew packages, and cleanup " 137 | echo "${NC}\n" 138 | ;; 139 | esac 140 | 141 | } 142 | 143 | 144 | case ${fn} in 145 | "list"|"help"|"usage") 146 | echo "$(printInfo)" 147 | for c in ${MacCategories[@]} 148 | do 149 | echo "$(usageList ${c})" 150 | done 151 | echo "$(printAdditionalHelp)" 152 | ;; 153 | "categories") 154 | echo "$(printInfo)" 155 | echo "\n${WHITEBOLD}mac CLI Categories: ${NC}\n" 156 | for c in "${MacCategories[@]}" 157 | do 158 | echo "${WHITEBOLD} >\t$c ${NC}" 159 | done 160 | echo "$(printAdditionalHelp)" 161 | ;; 162 | esac 163 | 164 | for c in "${MacCategories[@]}" 165 | do 166 | if [ "${c}" = "${fn}" ]; then 167 | echo "$(printInfo)" 168 | echo "\n${WHITEBOLD}Usage for 'mac ${c}'" 169 | echo "$(usageList ${c})" 170 | break 171 | fi 172 | done 173 | -------------------------------------------------------------------------------- /mac-cli/plugins/brew: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | #-------------------------------------------------------------------- 4 | # Homebrew Utilities 5 | #-------------------------------------------------------------------- 6 | 7 | case "$fn" in 8 | 9 | # Update Homebrew and installed packages 10 | "brew:update") 11 | echo "Updating Homebrew and its installed packages..." 12 | if [ "$echocommand" == "true" ]; then 13 | echo "${GREEN}brew update; brew upgrade; brew upgrade --cask; brew cleanup;\n${NC}" 14 | fi 15 | brew update; brew upgrade; brew upgrade --cask; brew cleanup; 16 | ;; 17 | 18 | esac 19 | -------------------------------------------------------------------------------- /mac-cli/plugins/dns: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | #-------------------------------------------------------------------- 4 | # DNS Utilities 5 | #-------------------------------------------------------------------- 6 | 7 | case "$fn" in 8 | 9 | # List DNS server(s) 10 | "dns:list") 11 | echo "List of the DNS server(s):" 12 | cat /etc/resolv.conf | grep nameserver | cut -b 11- 13 | ;; 14 | 15 | # Add DNS server 16 | "dns:add") 17 | if [[ $2 =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]] 18 | then 19 | echo "Adding DNS server $2" 20 | sudo sh -c "echo nameserver '${2}' >> /etc/resolv.conf" 21 | else 22 | echo "Please provide a valid DNS server address to add." 23 | exit 1 24 | fi 25 | ;; 26 | 27 | # Remove DNS server 28 | "dns:remove") 29 | if [[ $2 =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]] 30 | then 31 | echo "Deleting DNS server ${2}..." 32 | sudo sed -i "" "/${2}/d" /etc/resolv.conf 33 | else 34 | echo "Please provide a valid DNS server address to remove." 35 | exit 1 36 | fi 37 | ;; 38 | 39 | # Flush DNS cache 40 | "dns:flush") 41 | VERSION=$(sw_vers -productVersion) 42 | echo "Flushing DNS cache..." 43 | if echo $VERSION | grep -E '^10\.10(\.[0-3])?$' >/dev/null 2>&1; then 44 | sudo discoveryutil mdnsflushcache 45 | elif echo $VERSION | grep -E '^10\.6(\.[0-8])?$' >/dev/null 2>&1; then 46 | sudo dscacheutil -flushcache 47 | else 48 | sudo killall -HUP mDNSResponder 49 | fi 50 | ;; 51 | 52 | esac -------------------------------------------------------------------------------- /mac-cli/plugins/general: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | #-------------------------------------------------------------------- 4 | # General Variables 5 | #-------------------------------------------------------------------- 6 | 7 | _W_DEVICE=${_W_DEVICE:-en0} 8 | 9 | #-------------------------------------------------------------------- 10 | # General Utilities 11 | #-------------------------------------------------------------------- 12 | 13 | case "$fn" in 14 | 15 | # Install macOS software updates, update installed Ruby gems, Homebrew, npm, pip and their installed packages 16 | "update") 17 | 18 | echo "Updating macOS..." 19 | if [ "$echocommand" == "true" ]; then 20 | echo "${GREEN}sudo softwareupdate -i -a;\n${NC}" 21 | fi 22 | sudo softwareupdate -i -a; 23 | 24 | echo "Updating Homebrew and its installed packages..." 25 | if [ "$echocommand" == "true" ]; then 26 | echo "${GREEN}brew update; brew upgrade; brew upgrade --cask; brew cleanup; \n${NC}" 27 | fi 28 | brew update; brew upgrade; brew upgrade --cask; brew cleanup; 29 | 30 | echo "Updating npm and its installed packages..." 31 | if [ "$echocommand" == "true" ]; then 32 | echo "${GREEN}npm install npm -g; npm update -g;\n${NC}" 33 | fi 34 | npm install npm -g; npm update -g; 35 | 36 | echo "Updating Yarn's installed packages..." 37 | if [ "$echocommand" == "true" ]; then 38 | echo "${GREEN}yarn global upgrade;\n${NC}" 39 | fi 40 | yarn global upgrade; 41 | 42 | echo "Updating installed Ruby gems..." 43 | if [ "$echocommand" == "true" ]; then 44 | echo "${GREEN}sudo gem update --system; sudo gem update\n${NC}" 45 | fi 46 | sudo gem update --system; sudo gem update 47 | 48 | echo "Updating installed pip packages..." 49 | if [ "$echocommand" == "true" ]; then 50 | echo "${GREEN}pip list --outdated --format=freeze --local | grep -v '^\-e' | cut -d = -f 1 | xargs -n1 pip install -U\n${NC}" 51 | fi 52 | pip list --outdated --format=freeze --local | grep -v '^\-e' | cut -d = -f 1 | xargs -n1 pip install -U 53 | 54 | if [ -x "$(command -v pip3)" ]; then 55 | echo "Updating installed pip3 packages..." 56 | if [ "$echocommand" == "true" ]; then 57 | echo "${GREEN}pip3 list --outdated --format=freeze --local | grep -v '^\-e' | cut -d = -f 1 | xargs -n1 pip3 install -U\n${NC}" 58 | fi 59 | pip3 list --outdated --format=freeze --local | grep -v '^\-e' | cut -d = -f 1 | xargs -n1 pip3 install -U 60 | fi 61 | 62 | if [ -f /usr/local/bin/apm ]; then 63 | echo "Updating Atom Packages..." 64 | if [ "$echocommand" == "true" ]; then 65 | echo "${GREEN}apm upgrade --no-confirm\n${NC}" 66 | fi 67 | apm upgrade --no-confirm 68 | fi 69 | ;; 70 | 71 | 72 | # Upgrade Mac CLI to the latest version 73 | "upgrade") 74 | if [ "$echocommand" == "true" ]; then 75 | echo "${GREEN}sh -c "$(curl -fsSL https://raw.githubusercontent.com/guarinogabriel/mac-cli/master/mac-cli/tools/update)"\n\n${NC}" 76 | fi 77 | sh -c "$(curl -fsSL https://raw.githubusercontent.com/guarinogabriel/mac-cli/master/mac-cli/tools/update)" 78 | ;; 79 | 80 | 81 | # Uninstall Mac CLI from your Mac 82 | "uninstall") 83 | if [ "$echocommand" == "true" ]; then 84 | echo "${GREEN}sh -c "$(curl -fsSL https://raw.githubusercontent.com/guarinogabriel/mac-cli/master/mac-cli/tools/uninstall)"\n\n${NC}" 85 | fi 86 | sh -c "$(curl -fsSL https://raw.githubusercontent.com/guarinogabriel/mac-cli/master/mac-cli/tools/uninstall)" 87 | ;; 88 | 89 | 90 | # Get macOS Info 91 | "info") 92 | printf "${GREEN}sw_vers\n${NC}" 93 | sw_vers 94 | ;; 95 | 96 | 97 | # Lock Mac 98 | "lock") 99 | if [ "$echocommand" == "true" ]; then 100 | echo "${GREEN}/System/Library/CoreServices/Menu\ Extras/User.menu/Contents/Resources/CGSession -suspend\n\n${NC}" 101 | fi 102 | /System/Library/CoreServices/Menu\ Extras/User.menu/Contents/Resources/CGSession -suspend 103 | ;; 104 | 105 | 106 | # Restart Mac 107 | "restart") 108 | if [ "$echocommand" == "true" ]; then 109 | echo "${GREEN}osascript -e 'tell app 'loginwindow' to «event aevtrrst»''\n\n${NC}" 110 | fi 111 | osascript -e 'tell app "loginwindow" to «event aevtrrst»' 112 | ;; 113 | 114 | 115 | # Sleep 116 | "sleep") 117 | if [ "$echocommand" == "true" ]; then 118 | echo "${GREEN}pmset sleepnow\n\n${NC}" 119 | fi 120 | pmset sleepnow 121 | ;; 122 | 123 | 124 | # Shutdown Mac 125 | "shutdown") 126 | if [ "$echocommand" == "true" ]; then 127 | echo "${GREEN}osascript -e 'tell app 'loginwindow' to «event aevtrsdn»'\n\n${NC}" 128 | fi 129 | osascript -e 'tell app "loginwindow" to «event aevtrsdn»' 130 | ;; 131 | 132 | # Uptime 133 | "uptime") 134 | if [ "$echocommand" == "true" ]; then 135 | echo "${GREEN}uptime\n\n${NC}" 136 | fi 137 | uptime 138 | ;; 139 | 140 | 141 | #List folders in current directory 142 | "folders:list") 143 | du -sk * | sort -rn 144 | ;; 145 | 146 | 147 | # Calculate folder size 148 | "folder:size") 149 | if [ "$echocommand" == "true" ]; then 150 | echo "${GREEN}du -sh .\n\n${NC}" 151 | fi 152 | echo "Calculating folder size..." 153 | echo "Folder size:" 154 | du -sh . 155 | ;; 156 | 157 | 158 | # Show hidden files 159 | "hidden:show") 160 | if [ "$echocommand" == "true" ]; then 161 | echo "${GREEN}defaults write com.apple.finder AppleShowAllFiles YES; killall Finder\n\n${NC}" 162 | fi 163 | defaults write com.apple.finder AppleShowAllFiles YES; killall Finder 164 | ;; 165 | 166 | 167 | # Hide hidden files 168 | "hidden:hide") 169 | if [ "$echocommand" == "true" ]; then 170 | echo "${GREEN}defaults write com.apple.finder AppleShowAllFiles NO; killall Finder\n\n${NC}" 171 | fi 172 | defaults write com.apple.finder AppleShowAllFiles NO; killall Finder 173 | ;; 174 | 175 | 176 | # Check bluetooth status 177 | "bluetooth:status") 178 | defaults read /Library/Preferences/com.apple.Bluetooth ControllerPowerState | \ 179 | awk '{ if($1 != 0) {print "Bluetooth: ON"} else { print "Bluetooth: OFF" } }' 180 | ;; 181 | 182 | 183 | # Enable bluetooth 184 | "bluetooth:enable") 185 | echo "${GREEN}Bluetooth enabled{NC}" 186 | sudo defaults write /Library/Preferences/com.apple.Bluetooth ControllerPowerState -int 1 && \ 187 | sudo killall -HUP bluetoothd 188 | ;; 189 | 190 | 191 | # Disable bluetooth 192 | "bluetooth:disable") 193 | echo "${GREEN}Bluetooth disabled${NC}" 194 | sudo defaults write /Library/Preferences/com.apple.Bluetooth ControllerPowerState -int 0 && \ 195 | sudo killall -HUP bluetoothd 196 | ;; 197 | 198 | 199 | # Check wifi status 200 | "wifi:status") 201 | /System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -I 202 | ;; 203 | 204 | 205 | # Check available wifi networks 206 | "wifi:scan") 207 | /System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -s 208 | ;; 209 | 210 | 211 | # Enable wifi 212 | "wifi:enable") 213 | echo "${GREEN}Wifi enabled${NC}" 214 | networksetup -setairportpower ${_W_DEVICE} on 215 | ;; 216 | 217 | 218 | # Disable wifi 219 | "wifi:disable") 220 | echo "${GREEN}Wifi disabled${NC}" 221 | networksetup -setairportpower ${_W_DEVICE} off 222 | ;; 223 | 224 | 225 | # Add blank space to the dock 226 | "dock:add-space") 227 | if [ ! -z "$firstParameter" -a "$firstParameter" != " " ]; then 228 | echo "${GREEN}Added $firstParameter new blank spaces to the dock${NC}" 229 | 230 | for i in `seq "$firstParameter"`; do 231 | defaults write com.apple.dock persistent-apps -array-add '{"tile-type"="spacer-tile";}' 232 | done 233 | else 234 | echo "${GREEN}Added new blank space to the dock${NC}" 235 | defaults write com.apple.dock persistent-apps -array-add '{"tile-type"="spacer-tile";}' 236 | fi 237 | 238 | killall Dock 239 | ;; 240 | 241 | 242 | # Start screensaver 243 | "screensaver") 244 | if [ "$echocommand" == "true" ]; then 245 | echo "${GREEN}open -a ScreenSaverEngine\n\n${NC}" 246 | fi 247 | open -a ScreenSaverEngine 248 | ;; 249 | 250 | 251 | # Eject all mounted volumes and disk 252 | "eject-all") 253 | if [ "$echocommand" == "true" ]; then 254 | echo "${GREEN}osascript -e 'tell application 'Finder' to eject (every disk whose ejectable is true)'\n\n${NC}" 255 | fi 256 | osascript -e 'tell application "Finder" to eject (every disk whose ejectable is true)' 257 | ;; 258 | 259 | 260 | # Get battery information 261 | "battery") 262 | if [ "$echocommand" == "true" ]; then 263 | echo "${GREEN}pmset -g batt\n\n${NC}" 264 | fi 265 | pmset -g batt 266 | ;; 267 | 268 | 269 | # Find text in current directory 270 | "find:text") 271 | 272 | if [ ! -z "$allParameters" -a "$allParameters" != " " ]; then 273 | echo "Please enter the extension to search (i.e.: csv): " 274 | 275 | read extension 276 | 277 | if [ ! -z "$extension" -a "$extension" != " " ]; then 278 | 279 | if [ "$echocommand" == "true" ]; then 280 | echo "${GREEN}find . -iname '*.${GRAY}${extension}${GREEN}' | xargs grep -in --color '${GRAY}${allParameters}${GREEN}'${NC}" 281 | fi 282 | echo "\nRecursively find '"$allParameters"' inside directory..." 283 | find . -iname "*.$extension" | xargs grep -in --color "$allParameters" 284 | 285 | else 286 | echo "Please introduce the extension of the files to search. E.g: csv" 287 | fi 288 | else 289 | echo "Please introduce text to search. E.g:" 290 | echo "mac find:text Sample Search Text" 291 | fi 292 | ;; 293 | 294 | 295 | # Find biggest files in current directory 296 | "find:biggest-files") 297 | if [ "$echocommand" == "true" ]; then 298 | echo "${GREEN}find . -type f -print0 | xargs -0 du | sort -n | tail -10 | cut -f2 | xargs -I{} du -sh {}${NC}" 299 | fi 300 | find . -type f -print0 | xargs -0 du | sort -n | tail -10 | cut -f2 | xargs -I{} du -sh {} 301 | ;; 302 | 303 | 304 | # Find biggest directories in current directory 305 | "find:biggest-directories") 306 | if [ "$echocommand" == "true" ]; then 307 | echo "${GREEN}find . -type d -print0 | xargs -0 du | sort -n | tail -10 | cut -f2 | xargs -I{} du -sh {}${NC}" 308 | fi 309 | find . -type d -print0 | xargs -0 du | sort -n | tail -10 | cut -f2 | xargs -I{} du -sh {} 310 | ;; 311 | 312 | 313 | # Extract Zip file 314 | "zip:extract") 315 | 316 | if [ ! -z "$firstParameter" -a "$firstParameter" != " " ]; then 317 | if [ "$echocommand" == "true" ]; then 318 | echo "${GREEN}unzip ${GRAY}${firstParameter}\n\n${NC}" 319 | fi 320 | unzip $firstParameter 321 | else 322 | echo "Please specify the Zip file to extract." 323 | echo "E.g.: zip:extract sample_file.zip" 324 | fi 325 | ;; 326 | 327 | 328 | # Compress Gzip file 329 | "gzip:compress") 330 | 331 | if [ ! -z "$firstParameter" -a "$firstParameter" != " " ]; then 332 | if [ "$echocommand" == "true" ]; then 333 | echo "${GREEN}gzip ${GRAY}${firstParameter}\n\n${NC}" 334 | fi 335 | gzip $firstParameter 336 | else 337 | echo "Please specify the file to compress." 338 | echo "E.g.: gzip:compress sample_file" 339 | fi 340 | ;; 341 | 342 | 343 | # Extract Gzip file 344 | "gzip:extract") 345 | 346 | if [ ! -z "$firstParameter" -a "$firstParameter" != " " ]; then 347 | if [ "$echocommand" == "true" ]; then 348 | echo "${GREEN}gzip -d ${GRAY}${firstParameter}\n\n${NC}" 349 | fi 350 | gzip -d $firstParameter 351 | else 352 | echo "Please specify the Gzip file to extract." 353 | echo "E.g.: gzip:extract sample_file.gz" 354 | fi 355 | ;; 356 | 357 | 358 | # Extract tar file 359 | "tar:extract") 360 | 361 | if [ ! -z "$firstParameter" -a "$firstParameter" != " " ]; then 362 | if [ "$echocommand" == "true" ]; then 363 | echo "${GREEN}tar -xvzf ${GRAY}${firstParameter}\n\n${NC}" 364 | fi 365 | tar -xvzf $firstParameter 366 | else 367 | echo "Please specify the tar file to extract." 368 | echo "E.g.: tar:extract sample_file.tgz" 369 | fi 370 | ;; 371 | 372 | 373 | # Compress file/folder using TAR with progress indicator 374 | "tar:compress") 375 | echo "Please enter the filename to save the .tgz file: " 376 | 377 | if [ ! -z "$firstParameter" -a "$firstParameter" != " " ]; then 378 | read filename 379 | 380 | if [ ! -z "$filename" -a "$filename" != " " ]; then 381 | if [ "$echocommand" == "true" ]; then 382 | echo "${GREEN}tar -czf${GRAY}: ${firstParameter}${GREEN} | (pv -p --timer --rate --bytes > '${GRAY}${filename}${GREEN}'.tgz)\n\n${NC}" 383 | fi 384 | tar -czf - $firstParameter | (pv -p --timer --rate --bytes > "$filename".tgz) 385 | else 386 | "Please specify the file name" 387 | fi 388 | else 389 | echo "Please specify the folder or directory to compress." 390 | echo "E.g.: tar:compress foldername" 391 | fi 392 | ;; 393 | 394 | 395 | # Search and replace string on file 396 | "search:replace") 397 | echo "Please enter the string to search on the file:" 398 | 399 | if [ ! -z "$firstParameter" -a "$firstParameter" != " " ]; then 400 | read searchString 401 | 402 | if [ ! -z "$searchString" -a "$searchString" != " " ]; then 403 | 404 | echo "Please enter the string that will replace the search string:" 405 | read replaceString 406 | 407 | if [ ! -z "$replaceString" -a "$replaceString" != " " ]; then 408 | 409 | if [ "$echocommand" == "true" ]; then 410 | echo "${GREEN}LC_CTYPE=C sed -i'' -e 's#${GRAY}${searchString}${GREEN}#${GRAY}${replaceString}${GREEN}#g' ${GRAY}${firstParameter}\n\n${NC}" 411 | fi 412 | LC_CTYPE=C sed -i'' -e 's#'"${searchString}"'#'"${replaceString}"'#g' $firstParameter 413 | 414 | else 415 | "Please specify the string to replace" 416 | fi 417 | 418 | else 419 | "Please specify the string to search" 420 | fi 421 | else 422 | echo "Please specify the file to perform the search and replace operation" 423 | echo "E.g.: search:replace /path/to/file.csv" 424 | fi 425 | ;; 426 | 427 | 428 | esac 429 | -------------------------------------------------------------------------------- /mac-cli/plugins/git: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | #-------------------------------------------------------------------- 4 | # Git Utilities 5 | #-------------------------------------------------------------------- 6 | 7 | case "$fn" in 8 | 9 | # Display local Git configuration 10 | "brew:git:config") 11 | 12 | if [ "$echocommand" == "true" ]; then 13 | echo "${GREEN}git config --list\n\n${NC}" 14 | fi 15 | git config --list 16 | ;; 17 | 18 | 19 | # Open current Git repository on Github 20 | "git:open") 21 | 22 | giturl=$(git config --get remote.origin.url) 23 | if [ "$giturl" == "" ] 24 | then 25 | echo "Not a git repository or no remote.origin.url set" 26 | exit 1; 27 | fi 28 | giturl=${giturl/git\@github\.com\:/https://github.com/} 29 | giturl=${giturl/\.git/\/} 30 | branch="$(git symbolic-ref HEAD 2>/dev/null)" || 31 | branch="(unnamed branch)" # detached HEAD 32 | branch=${branch##refs/heads/} 33 | giturl=$giturl 34 | open $giturl 35 | ;; 36 | 37 | 38 | # Create Git branch based on current branch 39 | "git:create:branch") 40 | 41 | if [ ! -z "$firstParameter" -a "$firstParameter" != " " ]; then 42 | if [ "$echocommand" == "true" ]; then 43 | echo "${GREEN}git checkout -b ${GRAY}$firstParameter\n\n${NC}" 44 | fi 45 | git checkout -b $firstParameter 46 | 47 | else 48 | echo "Please specify the name for the new branch" 49 | echo "E.g.: git:create:branch sample-branch" 50 | fi 51 | ;; 52 | 53 | 54 | # Get last update date for all branches in current project 55 | "git:branches") 56 | 57 | git for-each-ref --sort=committerdate refs/heads/ --format='%(HEAD) %(color:yellow)%(refname:short)%(color:reset) - %(color:red)%(objectname:short)%(color:reset) - %(contents:subject) - %(authorname) (%(color:green)%(committerdate:relative)%(color:reset))' 58 | ;; 59 | 60 | 61 | # Undo latest commit 62 | "git:undo-commit") 63 | 64 | if [ "$echocommand" == "true" ]; then 65 | echo "${GREEN}git reset --soft HEAD~\n\n${NC}" 66 | fi 67 | git reset --soft HEAD~ 68 | ;; 69 | 70 | 71 | # See latest commits IDs and titles for current branch 72 | "git:log") 73 | 74 | if [ "$echocommand" == "true" ]; then 75 | echo "${GREEN}git log --pretty=oneline\n\n${NC}" 76 | fi 77 | git log --pretty=oneline 78 | ;; 79 | 80 | 81 | # See all branches 82 | "git:branch") 83 | 84 | if [ "$echocommand" == "true" ]; then 85 | echo "${GREEN}git branch -a\n\n${NC}" 86 | fi 87 | git branch -a 88 | ;; 89 | 90 | 91 | # Rename Git branch 92 | "git:branch:rename") 93 | 94 | if [ ! -z "$firstParameter" -a "$firstParameter" != " " ]; then 95 | if [ "$echocommand" == "true" ]; then 96 | echo "${GREEN}git branch -m ${GRAY}$firstParameter\n\n${NC}" 97 | fi 98 | git branch -m $firstParameter 99 | 100 | else 101 | echo "Please specify the name of the branch to rename" 102 | echo "E.g.: git:branch:rename sample-branch" 103 | fi 104 | ;; 105 | 106 | 107 | # Remove local Git branch 108 | "git:branch:remove-local") 109 | 110 | if [ ! -z "$firstParameter" -a "$firstParameter" != " " ]; then 111 | if [ "$echocommand" == "true" ]; then 112 | echo "${GREEN}git branch -d ${GRAY}$firstParameter\n\n${NC}" 113 | fi 114 | git branch -d $firstParameter 115 | 116 | else 117 | echo "Please specify the name of the branch to remove" 118 | echo "E.g.: git:branch:remove-local sample-branch" 119 | fi 120 | ;; 121 | 122 | 123 | # Remove local and remote Git branch 124 | "git:branch:remove-remote") 125 | 126 | if [ ! -z "$firstParameter" -a "$firstParameter" != " " ]; then 127 | if [ "$echocommand" == "true" ]; then 128 | echo "${GREEN}git branch -d ${GRAY}$firstParameter\n\n${NC}" 129 | fi 130 | git branch -d $firstParameter 131 | if [ "$echocommand" == "true" ]; then 132 | echo "${GREEN}git push origin --delete ${GRAY}$firstParameter\n\n${NC}" 133 | fi 134 | git push origin --delete $firstParameter 135 | 136 | else 137 | echo "Please specify the name of the branch to remove" 138 | echo "E.g.: git:branch:remove-remote sample-branch" 139 | fi 140 | ;; 141 | 142 | 143 | # Check Git settings 144 | "git:config") 145 | 146 | if [ "$echocommand" == "true" ]; then 147 | echo "${GREEN}git config --list\n\n${NC}" 148 | fi 149 | git config --list 150 | ;; 151 | 152 | 153 | # Add removed files to staged files 154 | "git:add-removed") 155 | 156 | if [ "$echocommand" == "true" ]; then 157 | echo "${GREEN}git add -u\n\n${NC}" 158 | fi 159 | git add -u 160 | ;; 161 | 162 | 163 | # Open current Git repository URL 164 | "git:open") 165 | 166 | open `git remote -v | awk '/fetch/{print $2}' | sed -Ee 's#(git@|git://)#http://#' -e 's@com:@com/@'`| head -n1 167 | ;; 168 | 169 | 170 | # Get size of current Git repository 171 | "git:size") 172 | 173 | git bundle create tmp.bundle --all 174 | echo "\n\nCurrent Git repository size: " 175 | du -sh tmp.bundle 176 | rm tmp.bundle 177 | ;; 178 | 179 | 180 | esac -------------------------------------------------------------------------------- /mac-cli/plugins/network: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | #-------------------------------------------------------------------- 4 | # Network Utilities 5 | #-------------------------------------------------------------------- 6 | 7 | case "$fn" in 8 | 9 | # Internet connection speed test 10 | "speedtest") 11 | echo "Testing internet connection speed..." 12 | networkQuality -v 13 | ;; 14 | 15 | 16 | # List of used ports 17 | "ports") 18 | 19 | echo "Getting list of used ports..." 20 | if [ "$echocommand" == "true" ]; then 21 | echo "${GREEN}sudo lsof -iTCP -sTCP:LISTEN -P\n\n${NC}" 22 | fi 23 | sudo lsof -iTCP -sTCP:LISTEN -P 24 | ;; 25 | 26 | 27 | # Get local IP address 28 | "ip:local") 29 | 30 | local_ip=$(ipconfig getifaddr en0) 31 | if [ $? == 0 ]; then 32 | if [ "$echocommand" == "true" ]; then 33 | echo "${GREEN}ipconfig getifaddr en0\n\n${NC}" 34 | fi 35 | else 36 | if [ "$echocommand" == "true" ]; then 37 | echo "${GREEN}ipconfig getifaddr en1\n\n${NC}" 38 | fi 39 | local_ip=$(ipconfig getifaddr en1) 40 | fi 41 | echo "Your IP address is:\n${local_ip}" 42 | ;; 43 | 44 | 45 | # Get public IP address 46 | "ip:public") 47 | 48 | if [ "$echocommand" == "true" ]; then 49 | echo "${GREEN}wget http://ipinfo.io/ip -qO -\n\n${NC}" 50 | fi 51 | wget http://ipinfo.io/ip -qO - 52 | ;; 53 | 54 | esac 55 | -------------------------------------------------------------------------------- /mac-cli/plugins/performance: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | #-------------------------------------------------------------------- 4 | # Performance and maintenance Utilities 5 | #-------------------------------------------------------------------- 6 | 7 | case "$fn" in 8 | 9 | # See memory usage sorted by memory consumption 10 | "memory") 11 | 12 | if [ "$echocommand" == "true" ]; then 13 | echo "${GREEN}top -o MEM \n\n${NC}" 14 | fi 15 | top -o MEM 16 | ;; 17 | 18 | 19 | # Empty trash 20 | "trash:empty") 21 | 22 | if [ "$echocommand" == "true" ]; then 23 | echo "${GREEN}sudo rm -rf ~/.Trash/* \n\n${NC}" 24 | fi 25 | sudo rm -rf ~/.Trash/* 26 | ;; 27 | 28 | 29 | # Calculate trash size 30 | "trash:size") 31 | 32 | if [ "$echocommand" == "true" ]; then 33 | echo "${GREEN}du -sh ~/.Trash/ \n\n${NC}" 34 | fi 35 | echo "Trash size: " 36 | du -sh ~/.Trash/ 37 | ;; 38 | 39 | esac -------------------------------------------------------------------------------- /mac-cli/plugins/search: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | #-------------------------------------------------------------------- 4 | # Search Utilities 5 | #-------------------------------------------------------------------- 6 | 7 | case "$fn" in 8 | 9 | # Find files modified in the last N minutes 10 | "find:recent") 11 | 12 | echo "Searching for files modified in the last "$firstParameter" minutes..." 13 | if [ "$echocommand" == "true" ]; then 14 | echo "${GREEN}sudo find / -mmin ${GRAY}${firstParameter}${GREEN} -type f\n\n${NC}" 15 | fi 16 | sudo find / -mmin $firstParameter -type f 17 | ;; 18 | 19 | esac -------------------------------------------------------------------------------- /mac-cli/plugins/ssh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | #-------------------------------------------------------------------- 4 | # SSH Utilities 5 | #-------------------------------------------------------------------- 6 | 7 | case "$fn" in 8 | 9 | # Download file through SSH on current folder 10 | "ssh:download-file") 11 | 12 | if [ ! -z "$firstParameter" -a "$firstParameter" != " " ]; then 13 | 14 | echo "Please enter the server IP address or domain: " 15 | 16 | read ipaddress 17 | if [ ! -z "$ipaddress" -a "$ipaddress" != " " ]; then 18 | 19 | echo "Please enter username: " 20 | 21 | read username 22 | 23 | if [ ! -z "$username" -a "$username" != " " ]; then 24 | 25 | if [ "$echocommand" == "true" ]; then 26 | echo "${GREEN}scp ${GRAY}${username}@${ipaddress}:${firstparameter}${GREEN} .\n\n${NC}" 27 | fi 28 | scp $username@$ipaddress:$firstParameter . 29 | 30 | else 31 | "Please specify the username for the remote server" 32 | fi 33 | 34 | else 35 | "Please specify the server IP address or domain" 36 | fi 37 | 38 | else 39 | echo "Please specify the path to the file on the remote server to download" 40 | echo "E.g.: /home/sample/file.jpg" 41 | fi 42 | ;; 43 | 44 | 45 | # Download entire folder through SSH on current directory 46 | "ssh:download-folder") 47 | 48 | if [ ! -z "$firstParameter" -a "$firstParameter" != " " ]; then 49 | 50 | echo "Please enter the server IP address or domain: " 51 | 52 | read ipaddress 53 | if [ ! -z "$ipaddress" -a "$ipaddress" != " " ]; then 54 | 55 | echo "Please enter username: " 56 | 57 | read username 58 | 59 | if [ ! -z "$username" -a "$username" != " " ]; then 60 | 61 | if [ "$echocommand" == "true" ]; then 62 | echo "${GREEN}scp -r ${GRAY}${username}@${ipaddress}:${firstparameter}${GREEN} .\n\n${NC}" 63 | fi 64 | scp -r $username@$ipaddress:$firstParameter . 65 | 66 | else 67 | "Please specify the username for the remote server" 68 | fi 69 | 70 | else 71 | "Please specify the server IP address or domain" 72 | fi 73 | 74 | else 75 | echo "Please specify the path to the folder on the remote server to download" 76 | echo "E.g.: /home/sample/folder/" 77 | fi 78 | ;; 79 | 80 | 81 | # Sync local folder with remote folder using rsync through SSH (download remote folder to local folder) 82 | "ssh:sync:local") 83 | 84 | if [ ! -z "$firstParameter" -a "$firstParameter" != " " ]; then 85 | 86 | echo "Please enter the server IP address or domain: " 87 | 88 | read ipaddress 89 | if [ ! -z "$ipaddress" -a "$ipaddress" != " " ]; then 90 | 91 | echo "Please enter username: " 92 | 93 | read username 94 | 95 | if [ ! -z "$username" -a "$username" != " " ]; then 96 | 97 | echo "Please enter local folder to sync with the remote folder: " 98 | 99 | read localfolder 100 | 101 | if [ ! -z "$localfolder" -a "$localfolder" != " " ]; then 102 | if [ "$echocommand" == "true" ]; then 103 | echo "${GREEN}rsync -a --progress ${GRAY}${username}@${ipaddress}:${firstparameter} ${localfolder}${GREEN}\n\n${NC}" 104 | fi 105 | rsync -a --progress ${username}@${ipaddress}:${firstparameter} ${localfolder} 106 | 107 | else 108 | "Please specify the local folder to sync with the remote folder" 109 | fi 110 | else 111 | "Please specify the username for the remote server" 112 | fi 113 | 114 | else 115 | "Please specify the server IP address or domain" 116 | fi 117 | 118 | else 119 | echo "Please specify the remote folder path to sync" 120 | echo "E.g.: mac ssh:sync:remote /var/www/html/media/" 121 | fi 122 | ;; 123 | 124 | 125 | # Sync remote folder with local folder using rsync through SSH (upload local folder to remote folder) 126 | "ssh:sync:remote") 127 | 128 | if [ ! -z "$firstParameter" -a "$firstParameter" != " " ]; then 129 | 130 | echo "Please enter the server IP address or domain: " 131 | 132 | read ipaddress 133 | if [ ! -z "$ipaddress" -a "$ipaddress" != " " ]; then 134 | 135 | echo "Please enter username: " 136 | 137 | read username 138 | 139 | if [ ! -z "$username" -a "$username" != " " ]; then 140 | 141 | echo "Please enter local folder to sync from the remove folder: " 142 | 143 | read localfolder 144 | 145 | if [ ! -z "$localfolder" -a "$localfolder" != " " ]; then 146 | if [ "$echocommand" == "true" ]; then 147 | echo "${GREEN}rsync -a ${localfolder} ${username}@${ipaddress}:${firstparameter}\n\n${NC}" 148 | fi 149 | rsync -a --progress ${localfolder} ${username}@${ipaddress}:${firstparameter} 150 | 151 | else 152 | "Please specify the local folder to sync from the remote folder" 153 | fi 154 | else 155 | "Please specify the username for the remote server" 156 | fi 157 | 158 | else 159 | "Please specify the server IP address or domain" 160 | fi 161 | 162 | else 163 | echo "Please specify the remote folder path to sync" 164 | echo "E.g.: mac ssh:sync:remote /var/www/html/media/" 165 | fi 166 | ;; 167 | 168 | 169 | # Upload file to remote server through SSH 170 | "ssh:upload") 171 | 172 | if [ ! -z "$firstParameter" -a "$firstParameter" != " " ]; then 173 | 174 | echo "Please enter the server IP address or domain: " 175 | 176 | read ipaddress 177 | 178 | if [ ! -z "$ipaddress" -a "$ipaddress" != " " ]; then 179 | 180 | echo "Please enter username: " 181 | 182 | read username 183 | 184 | if [ ! -z "$username" -a "$username" != " " ]; then 185 | 186 | echo "Please enter path on the remote server to upload the file: " 187 | 188 | read remotePath 189 | 190 | if [ ! -z "$remotePath" -a "$remotePath" != " " ]; then 191 | 192 | if [ "$echocommand" == "true" ]; then 193 | echo "${GREEN}scp ${GRAY}${firstParameter} ${username}@${ipaddress}:${remotePath}${GREEN}\n\n${NC}" 194 | fi 195 | scp $firstParameter $username@$ipaddress:$remotePath 196 | 197 | else 198 | "Please specify the path on the remote server to upload the file" 199 | fi 200 | 201 | else 202 | "Please specify the username for the remote server" 203 | fi 204 | 205 | else 206 | "Please specify the server IP address or domain" 207 | fi 208 | 209 | else 210 | echo "Please specify the path to the file to upload to the remote server" 211 | echo "E.g.: /user/example/documents/file.pdf" 212 | fi 213 | ;; 214 | 215 | 216 | # SSH key Utilities 217 | "ssh:public-key") 218 | 219 | if [ "$echocommand" == "true" ]; then 220 | echo "${GREEN}pbcopy < ~/.ssh/id_rsa.pub \n\n${NC}" 221 | fi 222 | pbcopy < ~/.ssh/id_rsa.pub 223 | ;; 224 | 225 | 226 | esac -------------------------------------------------------------------------------- /mac-cli/plugins/volume: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | #-------------------------------------------------------------------- 4 | # Volume Utilities 5 | #-------------------------------------------------------------------- 6 | 7 | case "$fn" in 8 | 9 | # Get current volume 10 | "volume") 11 | if [ ! -z "$firstParameter" -a "$firstParameter" != " " ]; then 12 | osascript -e "set volume output volume $firstParameter" 13 | echo "${WHITEBOLD}Vol:${NC} ${GREEN}${firstParameter}%${NC}" 14 | else 15 | echo "${WHITEBOLD}Vol:${NC} ${GREEN}$(osascript -e "output volume of (get volume settings)")% ${NC}" 16 | 17 | fi 18 | ;; 19 | 20 | # Is volume muted? 21 | "volume:ismute") 22 | echo "${WHITEBOLD}Mute:${NC} ${GREEN}$(osascript -e 'output muted of (get volume settings)')${NC}" 23 | ;; 24 | 25 | # Mute volume 26 | "volume:mute") 27 | osascript -e "set volume output muted true" 28 | echo "${WHITEBOLD}Mute:${NC} ${GREEN}true${NC}" 29 | ;; 30 | 31 | # Unmute volume 32 | "volume:unmute") 33 | osascript -e "set volume output muted false" 34 | echo "${WHITEBOLD}Mute:${NC} ${GREEN}false${NC}" 35 | ;; 36 | 37 | esac 38 | -------------------------------------------------------------------------------- /mac-cli/tools/install: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Colors 4 | GREEN='\033[0;32m' 5 | LIGHTGREEN='\033[1;32m' 6 | NC='\033[1;37m' 7 | LIGHTBLUE='\033[01;34m' 8 | NC='\033[0m' # No Color 9 | 10 | # In directory 11 | PACKAGE_DIRECTORY="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 12 | suggest_current(){ 13 | case "$1" in 14 | "editor") 15 | current=$EDITOR 16 | ;; 17 | *) 18 | current=$(which $1) 19 | ;; 20 | esac 21 | if [ -n $current ]; then 22 | echo $current | pbcopy 23 | echo "${NC}Press ⌘V to insert current (${current})" 24 | fi 25 | } 26 | 27 | main() { 28 | 29 | echo "${LIGHTBLUE}================================================" 30 | echo " Mac CLI Installer" 31 | echo "================================================${NC}\n" 32 | 33 | git clone https://github.com/guarinogabriel/mac-cli.git --depth 1 && cd mac-cli 34 | 35 | printf "${LIGHTGREEN}" 36 | read -r -p "Would you like Mac CLI to show you the commands that are run on each mac command? (Yes / No)" response 37 | case $response in 38 | [yY][eE][sS]|[yY]) 39 | LC_CTYPE=C sed -i'' -e 's#echocommand="false"#echocommand="true"#g' "$PACKAGE_DIRECTORY/mac-cli/mac" 40 | ;; 41 | *) 42 | ;; 43 | esac 44 | printf "${NC}" 45 | 46 | sudo cp "$PACKAGE_DIRECTORY/mac-cli/mac" /usr/local/bin/mac 47 | sudo cp -r "$PACKAGE_DIRECTORY/mac-cli/mac-cli/" /usr/local/bin/mac-cli 48 | sudo chmod -R +x /usr/local/bin/mac-cli/* 49 | 50 | if ! [ -x "$(command -v brew)" ]; then 51 | echo "Installing Homebrew..." 52 | echo "${GREEN}/usr/bin/ruby -e '\$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)'\n${NC}" 53 | /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" 54 | fi 55 | 56 | if ! [ -x "$(command -v git)" ]; then 57 | echo "Installing Git..." 58 | echo "${GREEN}brew install git\n${NC}" 59 | brew install git 60 | fi 61 | 62 | if ! [ -x "$(command -v pv)" ]; then 63 | echo "Installing pv (Pipe Viewer)..." 64 | echo "${GREEN}brew install pv\n${NC}" 65 | brew install pv 66 | fi 67 | 68 | if ! [ -x "$(command -v wget)" ]; then 69 | echo "Installing wget..." 70 | printf "${GREEN}brew install wget\n${NC}" 71 | brew install wget 72 | fi 73 | 74 | if ! brew list | grep -q bash-completion ; then 75 | 76 | echo "Installing bash-completion\n" 77 | echo "${GREEN}brew install bash-completion\n\n${NC}" 78 | brew install bash-completion 79 | echo 'if [ -f $(brew --prefix)/etc/bash_completion ]; then source $(brew --prefix)/etc/bash_completion; fi' >> ~/.bashrc 80 | echo "Setting up Mac-CLI bash-completion\n" 81 | 82 | if [ -d /usr/local/etc/bash_completion.d/ ]; then 83 | cp /usr/local/bin/mac-cli/completion/bash_completion /usr/local/etc/bash_completion.d/mac 84 | fi 85 | 86 | else 87 | 88 | echo "Setting up Mac-CLI bash-completion\n" 89 | 90 | if [ -d $(brew --prefix)/etc/bash_completion.d/ ]; then 91 | cp /usr/local/bin/mac-cli/completion/bash_completion $(brew --prefix)/etc/bash_completion.d/mac 92 | echo 'if [ -f $(brew --prefix)/etc/bash_completion ]; then source $(brew --prefix)/etc/bash_completion; fi' >> ~/.bashrc 93 | fi 94 | 95 | fi 96 | 97 | # 98 | # Check if fish shell is installed and prompt user to copy fish_completion 99 | # 100 | if $(cat /etc/shells | grep -q fish) && [ -d ~/.config/fish ]; 101 | then 102 | printf "${LIGHTGREEN}" 103 | read -r -p "Would you like to install fish shell suggestions/tab completion? (Yes / No) " response 104 | case $response in 105 | [yY][eE][sS]|[yY]) 106 | echo "Setting up Mac-CLI Fish completion" 107 | if [ -d ~/.config/fish/completions ];then 108 | cp /usr/local/bin/mac-cli/completion/fish_completion ~/.config/fish/completions/mac.fish 109 | else 110 | mkdir ~/.config/fish/completions && cp /usr/local/bin/mac-cli/completion/fish_completion ~/.config/fish/completions/mac.fish 111 | fi 112 | ;; 113 | *) 114 | ;; 115 | esac 116 | printf "${NC}" 117 | fi 118 | } 119 | 120 | main 121 | -------------------------------------------------------------------------------- /mac-cli/tools/uninstall: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | GREEN='\033[0;32m' 4 | NC='\033[0m' # No Color 5 | 6 | main() { 7 | echo "Uninstalling Mac CLI..." 8 | rm /usr/local/bin/mac 9 | rm -rf /usr/local/bin/mac-cli 10 | echo "${GREEN}Mac CLI has been uninstalled\n${NC}" 11 | } 12 | 13 | main -------------------------------------------------------------------------------- /mac-cli/tools/update: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | GREEN='\033[0;32m' 4 | NC='\033[0m' # No Color 5 | 6 | main() { 7 | echo "Upgrading Mac CLI..." 8 | rm /usr/local/bin/mac 9 | rm -rf /usr/local/bin/mac-cli 10 | if [ -d ~/Downloads/mac-cli-update/ ]; then 11 | rm -rf ~/Downloads/mac-cli-update/ 12 | fi 13 | mkdir ~/Downloads/mac-cli-update/ && cd ~/Downloads/mac-cli-update/ 14 | sh -c "$(curl -fsSL https://raw.githubusercontent.com/guarinogabriel/mac-cli/master/mac-cli/tools/install)" && cd - 15 | echo "${GREEN}Mac CLI has been updated to the latest version\n${NC}" 16 | } 17 | 18 | main --------------------------------------------------------------------------------