Última atividade 2 weeks ago

Cross-platform Zsh setup scripts and managed dotfiles with Oh My Zsh framework, Starship prompt, aliases, functions, and path configuration.

Revisão 9a02ba86ed92b196bf669a78a9f8b71969d021ee

README.md Bruto

Bash Script Installer for Zsh

The "Bash Script Installer" simplifies the setup of Zsh.

Zsh

Ubuntu

bash -c "$(curl -fsSL https://opengist.rmrf.online/weehong/f0d940c3c1214bf5b7996195199fdc09/raw/HEAD/zsh_ubuntu.sh)"

MacOS

bash -c "$(curl -fsSL https://opengist.rmrf.online/weehong/f0d940c3c1214bf5b7996195199fdc09/raw/HEAD/zsh_macos.sh)"
zsh_macos.sh Bruto
1#!/bin/bash
2set -euo pipefail
3
4# =============================
5# COLORS & LOGGING
6# =============================
7RED='\033[0;31m'
8GREEN='\033[0;32m'
9YELLOW='\033[1;33m'
10BLUE='\033[0;34m'
11NC='\033[0m'
12
13log() { echo -e "${BLUE}[INFO]${NC} $*"; }
14ok() { echo -e "${GREEN}[OK]${NC} $*"; }
15warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
16err() { echo -e "${RED}[ERROR]${NC} $*" >&2; }
17
18# =============================
19# CONFIG
20# =============================
21CONFIG_FILES=(
22 ".alias|https://gist.githubusercontent.com/weehongkoh/72bdb76beacacf2ca3dd39a72395b9ee/raw/alias"
23 ".func|https://gist.githubusercontent.com/weehongkoh/72bdb76beacacf2ca3dd39a72395b9ee/raw/func"
24 ".pathrc|https://gist.githubusercontent.com/weehongkoh/72bdb76beacacf2ca3dd39a72395b9ee/raw/pathrc"
25 ".sourcerc|https://gist.githubusercontent.com/weehongkoh/72bdb76beacacf2ca3dd39a72395b9ee/raw/sourcerc"
26 ".vimrc|https://gist.githubusercontent.com/weehongkoh/72bdb76beacacf2ca3dd39a72395b9ee/raw/vimrc"
27 ".zshrc|https://gist.githubusercontent.com/weehongkoh/72bdb76beacacf2ca3dd39a72395b9ee/raw/zshrc"
28)
29
30# =============================
31# REQUIREMENTS
32# =============================
33check_requirements() {
34 if [[ $EUID -eq 0 ]]; then
35 err "Do not run as root on macOS"
36 exit 1
37 fi
38}
39
40# =============================
41# INSTALLATION FUNCTIONS
42# =============================
43configure_git() {
44 log "Configuring Git..."
45 read -p "Git name (leave empty to skip): " name
46 read -p "Git email (leave empty to skip): " email
47
48 if [[ -n "$name" ]]; then
49 git config --global user.name "$name"
50 fi
51 if [[ -n "$email" ]]; then
52 git config --global user.email "$email"
53 fi
54 ok "Git configured"
55}
56
57install_oh_my_zsh() {
58 if [[ -d "$HOME/.oh-my-zsh" ]]; then
59 ok "Oh My Zsh already installed"
60 return
61 fi
62
63 log "Installing Oh My Zsh..."
64 RUNZSH=no CHSH=no KEEP_ZSHRC=yes \
65 sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
66 ok "Oh My Zsh installed"
67}
68
69install_plugins() {
70 log "Installing plugins..."
71 local dir="${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/plugins"
72 [[ -d "$dir/zsh-autosuggestions" ]] || git clone https://github.com/zsh-users/zsh-autosuggestions "$dir/zsh-autosuggestions"
73 [[ -d "$dir/zsh-syntax-highlighting" ]] || git clone https://github.com/zsh-users/zsh-syntax-highlighting "$dir/zsh-syntax-highlighting"
74 ok "Plugins installed"
75}
76
77install_theme() {
78 log "Installing Spaceship theme..."
79 local themes="${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/themes"
80 local dir="$themes/spaceship-prompt"
81 [[ -d "$dir" ]] || git clone https://github.com/spaceship-prompt/spaceship-prompt.git "$dir" --depth=1
82 ln -sf "$dir/spaceship.zsh-theme" "$themes/spaceship.zsh-theme"
83 ok "Theme installed"
84}
85
86clean_macos_aliases() {
87 local alias_file="$HOME/.alias"
88 if [[ -f "$alias_file" ]]; then
89 log "Patching .alias for macOS..."
90 sed -i '' '/# System update & cleanup/,/sudo apt-get clean/d' "$alias_file"
91 sed -i '' '/# xclip shortcuts/,/xclip -selection clipboard/d' "$alias_file"
92 sed -i '' '/./,$!d' "$alias_file"
93 ok "macOS incompatibilities removed from .alias"
94 fi
95}
96
97clean_func_file() {
98 local func_file="$HOME/.func"
99 if [[ -f "$func_file" ]]; then
100 log "Patching .func to remove 'open' function (WSL/Explorer specific)..."
101
102 # Deletes from the comment line containing 'Function: open' down to the closing brace }
103 # This preserves the native macOS 'open' command.
104 sed -i '' '/# Function: open/,/^}/d' "$func_file"
105
106 # Trim leading blank lines that might remain at the top
107 sed -i '' '/./,$!d' "$func_file"
108
109 ok "'open' function removed from .func"
110 fi
111}
112
113download_configs() {
114 log "Downloading custom config files..."
115 local backup="$HOME/.config_backup_$(date +%Y%m%d_%H%M%S)"
116 mkdir -p "$backup"
117
118 for entry in "${CONFIG_FILES[@]}"; do
119 local f="${entry%%|*}"
120 local url="${entry##*|}"
121
122 if [[ -f "$HOME/$f" ]]; then
123 cp "$HOME/$f" "$backup/"
124 fi
125 log "Fetching $f ..."
126 curl -fsSL "$url" -o "$HOME/$f" || warn "Failed to download $f"
127 done
128
129 # Run cleanup patches
130 clean_macos_aliases
131 clean_func_file
132
133 ok "Configs downloaded (Backup at $backup)"
134}
135
136update_zshrc() {
137 local zshrc="$HOME/.zshrc"
138 log "Updating .zshrc..."
139
140 if [[ ! -f "$zshrc" ]]; then
141 warn ".zshrc not found, creating new one..."
142 touch "$zshrc"
143 fi
144
145 grep -q 'ZSH_THEME="spaceship"' "$zshrc" || sed -i '' 's/ZSH_THEME=".*"/ZSH_THEME="spaceship"/' "$zshrc"
146 grep -q 'zsh-autosuggestions' "$zshrc" || sed -i '' 's/plugins=(/plugins=(zsh-autosuggestions /' "$zshrc"
147 grep -q 'zsh-syntax-highlighting' "$zshrc" || sed -i '' 's/plugins=(/plugins=(zsh-syntax-highlighting /' "$zshrc"
148 ok ".zshrc updated with plugins and theme"
149}
150
151switch_shell() {
152 log "Starting Zsh session..."
153 echo -e "${YELLOW}Type 'exit' to return to this installer menu.${NC}"
154 echo "----------------------------------------"
155 zsh -l
156 echo "----------------------------------------"
157 ok "Returned from Zsh session"
158}
159
160# =============================
161# INTERACTIVE MENU
162# =============================
163show_menu() {
164 echo "==========================================="
165 echo "macOS Zsh Setup - Choose what to do"
166 echo "==========================================="
167 echo " 0) Run ALL steps (1-7)"
168 echo " 1) Configure Git"
169 echo " 2) Install Oh My Zsh"
170 echo " 3) Install plugins (autosuggestions, syntax highlighting)"
171 echo " 4) Install Spaceship theme"
172 echo " 5) Download custom configs (~/.alias, .func, .vimrc, etc.)"
173 echo " 6) Update ~/.zshrc for plugins & theme"
174 echo " 7) Switch to Zsh (Temporary Sub-shell)"
175 echo " 8) Quit"
176 echo "==========================================="
177}
178
179run_choices() {
180 local input
181 read -p "Select: " input
182 input="${input//,/ }"
183
184 local -a to_run=()
185 local -a to_exclude=()
186
187 for item in $input; do
188 if [[ "$item" == !* ]]; then
189 to_exclude+=("${item:1}")
190 elif [[ "$item" == "0" ]]; then
191 to_run+=(1 2 3 4 5 6 7)
192 else
193 to_run+=("$item")
194 fi
195 done
196
197 if [[ ${#to_run[@]} -gt 0 ]]; then
198 for choice in "${to_run[@]}"; do
199 local skip=false
200
201 # Array empty-check for older Bash versions (Fixes 'unbound variable' error)
202 if [[ ${#to_exclude[@]} -gt 0 ]]; then
203 for ex in "${to_exclude[@]}"; do
204 if [[ "$choice" == "$ex" ]]; then
205 skip=true; break
206 fi
207 done
208 fi
209
210 $skip && continue
211
212 case "$choice" in
213 1) configure_git ;;
214 2) install_oh_my_zsh ;;
215 3) install_plugins ;;
216 4) install_theme ;;
217 5) download_configs ;;
218 6) update_zshrc ;;
219 7) switch_shell ;;
220 8) exit 0 ;;
221 *) warn "Skipping invalid option: $choice" ;;
222 esac
223 echo
224 done
225 fi
226}
227
228# =============================
229# MAIN
230# =============================
231main() {
232 check_requirements
233 while true; do
234 show_menu
235 run_choices
236 read -p "Do you want to run more options? (y/n): " again
237 [[ "$again" =~ ^[Yy]$ ]] || break
238 done
239 ok "macOS configuration complete!"
240}
241
242main "$@"
zsh_ubuntu.sh Bruto
1#!/bin/bash
2set -euo pipefail
3
4# =============================
5# COLORS & LOGGING
6# =============================
7RED='\033[0;31m'
8GREEN='\033[0;32m'
9YELLOW='\033[1;33m'
10BLUE='\033[0;34m'
11NC='\033[0m'
12
13log() { echo -e "${BLUE}[INFO]${NC} $*"; }
14ok() { echo -e "${GREEN}[OK]${NC} $*"; }
15warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
16err() { echo -e "${RED}[ERROR]${NC} $*" >&2; }
17
18# =============================
19# FLAGS & CONFIG
20# =============================
21SKIP_PACKAGES=false
22SKIP_GIT_CONFIG=false
23SKIP_SHELL_CHANGE=false
24CUSTOM_CONFIG=false
25SKIP_XCLIP=false
26INSTALL_HOMEBREW=false
27
28declare -A CONFIG_FILES=(
29 [".alias"]="https://gist.githubusercontent.com/weehongkoh/72bdb76beacacf2ca3dd39a72395b9ee/raw/alias"
30 [".func"]="https://gist.githubusercontent.com/weehongkoh/72bdb76beacacf2ca3dd39a72395b9ee/raw/func"
31 [".pathrc"]="https://gist.githubusercontent.com/weehongkoh/72bdb76beacacf2ca3dd39a72395b9ee/raw/pathrc"
32 [".sourcerc"]="https://gist.githubusercontent.com/weehongkoh/72bdb76beacacf2ca3dd39a72395b9ee/raw/sourcerc"
33 [".vimrc"]="https://gist.githubusercontent.com/weehongkoh/72bdb76beacacf2ca3dd39a72395b9ee/raw/vimrc"
34 [".zshrc"]="https://gist.githubusercontent.com/weehongkoh/72bdb76beacacf2ca3dd39a72395b9ee/raw/zshrc"
35)
36
37# =============================
38# OS DETECTION
39# =============================
40detect_os() {
41 if [ -f /etc/os-release ]; then
42 . /etc/os-release
43 echo "$ID"
44 else
45 echo "unknown"
46 fi
47}
48
49# =============================
50# REQUIREMENTS
51# =============================
52check_requirements() {
53 # Fixed to prevent silent failure with 'set -e'
54 if [[ $EUID -eq 0 ]]; then
55 err "Do not run as root"
56 exit 1
57 fi
58 if ! command -v sudo >/dev/null; then
59 err "sudo required"
60 exit 1
61 fi
62}
63
64# =============================
65# INSTALLATION FUNCTIONS
66# =============================
67update_system() {
68 $SKIP_PACKAGES && return
69 log "Updating system..."
70 sudo apt-get update -y
71 sudo apt-get upgrade -y
72 ok "System updated"
73}
74
75install_packages() {
76 $SKIP_PACKAGES && return
77 log "Installing core packages..."
78 sudo apt-get install -y \
79 zsh git vim curl wget unzip zip build-essential xz-utils
80 ok "Packages installed"
81}
82
83set_timezone() {
84 log "Setting timezone to Asia/Singapore..."
85 sudo timedatectl set-timezone Asia/Singapore
86 ok "Timezone set to Asia/Singapore"
87}
88
89install_xclip() {
90 local os
91 os=$(detect_os)
92 [[ "$os" != "ubuntu" && "$os" != "debian" ]] && return 0
93 $SKIP_XCLIP && return 0
94 command -v xclip >/dev/null && ok "xclip already installed" && return 0
95
96 read -r -p "Install xclip? (y/N): " r
97 case "$r" in
98 [Yy]) sudo apt-get install -y xclip; ok "xclip installed" ;;
99 *) log "Skipping xclip installation" ;;
100 esac
101}
102
103configure_git() {
104 $SKIP_GIT_CONFIG && return
105 log "Configuring Git..."
106 read -p "Git name (leave empty to skip): " name
107 read -p "Git email (leave empty to skip): " email
108 [[ -n "$name" ]] && git config --global user.name "$name"
109 [[ -n "$email" ]] && git config --global user.email "$email"
110 ok "Git configured"
111}
112
113install_homebrew() {
114 ! $INSTALL_HOMEBREW && return
115 command -v brew >/dev/null && ok "Homebrew already installed" && return
116 log "Installing Homebrew..."
117 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
118 ok "Homebrew installed"
119}
120
121configure_shell() {
122 $SKIP_SHELL_CHANGE && return
123 log "Changing default shell to zsh..."
124 local zsh_path
125 zsh_path=$(command -v zsh)
126 grep -qx "$zsh_path" /etc/shells || echo "$zsh_path" | sudo tee -a /etc/shells >/dev/null
127 sudo chsh -s "$zsh_path" "$USER"
128 ok "Shell changed (requires logout/login to take effect)"
129}
130
131install_oh_my_zsh() {
132 [[ -d "$HOME/.oh-my-zsh" ]] && ok "Oh My Zsh already installed" && return
133 log "Installing Oh My Zsh..."
134 # Keep zshrc ensures we don't blow away configs if they exist
135 RUNZSH=no CHSH=no KEEP_ZSHRC=yes \
136 sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
137 ok "Oh My Zsh installed"
138}
139
140install_plugins() {
141 log "Installing plugins..."
142 local dir="${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/plugins"
143 [[ -d "$dir/zsh-autosuggestions" ]] || git clone https://github.com/zsh-users/zsh-autosuggestions "$dir/zsh-autosuggestions"
144 [[ -d "$dir/zsh-syntax-highlighting" ]] || git clone https://github.com/zsh-users/zsh-syntax-highlighting "$dir/zsh-syntax-highlighting"
145 ok "Plugins installed"
146}
147
148install_theme() {
149 log "Installing Spaceship theme..."
150 local themes="${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/themes"
151 local dir="$themes/spaceship-prompt"
152 [[ -d "$dir" ]] || git clone https://github.com/spaceship-prompt/spaceship-prompt.git "$dir" --depth=1
153 ln -sf "$dir/spaceship.zsh-theme" "$themes/spaceship.zsh-theme"
154 ok "Theme installed"
155}
156
157download_configs() {
158 log "Downloading custom config files..."
159 local backup="$HOME/.config_backup_$(date +%Y%m%d_%H%M%S)"
160 mkdir -p "$backup"
161 for f in "${!CONFIG_FILES[@]}"; do
162 if [[ -f "$HOME/$f" ]]; then
163 cp "$HOME/$f" "$backup/"
164 fi
165 log "Fetching $f ..."
166 curl -fsSL "${CONFIG_FILES[$f]}" -o "$HOME/$f" || warn "Failed to download $f"
167 done
168 ok "Configs downloaded (Backup at $backup)"
169}
170
171update_zshrc() {
172 local zshrc="$HOME/.zshrc"
173 log "Updating .zshrc..."
174
175 # Create zshrc if missing to prevent errors
176 if [[ ! -f "$zshrc" ]]; then
177 warn ".zshrc not found, creating new one..."
178 touch "$zshrc"
179 fi
180
181 # Use || true to prevent 'set -e' from exiting if grep finds nothing
182 grep -q 'ZSH_THEME="spaceship"' "$zshrc" || sed -i 's/ZSH_THEME=".*"/ZSH_THEME="spaceship"/' "$zshrc"
183 grep -q 'zsh-autosuggestions' "$zshrc" || sed -i 's/plugins=(/plugins=(zsh-autosuggestions /' "$zshrc"
184 grep -q 'zsh-syntax-highlighting' "$zshrc" || sed -i 's/plugins=(/plugins=(zsh-syntax-highlighting /' "$zshrc"
185 ok ".zshrc updated with plugins and theme"
186}
187
188switch_shell() {
189 $SKIP_SHELL_CHANGE && return
190
191 log "Starting Zsh session..."
192 echo -e "${YELLOW}Type 'exit' to return to this installer menu.${NC}"
193 echo "----------------------------------------"
194
195 # Run zsh as a subprocess, not exec
196 zsh -l
197
198 echo "----------------------------------------"
199 ok "Returned from Zsh session"
200}
201
202# =============================
203# INTERACTIVE MENU
204# =============================
205show_menu() {
206 echo "==========================================="
207 echo "Zsh Installer - Choose what to do"
208 echo "==========================================="
209 echo " 0) Run ALL steps (1-13)"
210 echo " 1) Update system packages"
211 echo " 2) Install core packages (zsh, git, vim, etc.)"
212 echo " 3) Set Timezone (Asia/Singapore)"
213 echo " 4) Install xclip"
214 echo " 5) Configure Git"
215 echo " 6) Install Homebrew"
216 echo " 7) Configure shell (chsh - sets default shell)"
217 echo " 8) Install Oh My Zsh"
218 echo " 9) Install plugins (autosuggestions, syntax highlighting)"
219 echo "10) Install Spaceship theme"
220 echo "11) Download custom configs (~/.alias, .vimrc, etc.)"
221 echo "12) Update ~/.zshrc for plugins & theme"
222 echo "13) Switch to Zsh (Temporary Sub-shell)"
223 echo "14) Quit"
224 echo "==========================================="
225 echo "Inputs: '0' (All), '2 3 7' (Specific), '0 !4 !6' (All except 4 and 6)"
226}
227
228run_choices() {
229 local input
230 read -p "Select: " input
231 input="${input//,/ }" # replace commas with spaces
232
233 local -a to_run=()
234 local -a to_exclude=()
235
236 # Parse positive selections and negative exclusions
237 for item in $input; do
238 if [[ "$item" == !* ]]; then
239 to_exclude+=("${item:1}") # Strip the '!' character
240 elif [[ "$item" == "0" ]]; then
241 to_run+=(1 2 3 4 5 6 7 8 9 10 11 12 13)
242 else
243 to_run+=("$item")
244 fi
245 done
246
247 # Loop through intended runs and apply exclusions
248 for choice in "${to_run[@]}"; do
249
250 local skip=false
251 for ex in "${to_exclude[@]}"; do
252 if [[ "$choice" == "$ex" ]]; then
253 skip=true
254 break
255 fi
256 done
257
258 $skip && continue
259
260 case "$choice" in
261 1) update_system ;;
262 2) install_packages ;;
263 3) set_timezone ;;
264 4) install_xclip ;;
265 5) configure_git ;;
266 6) install_homebrew ;;
267 7) configure_shell ;;
268 8) install_oh_my_zsh ;;
269 9) install_plugins ;;
270 10) install_theme ;;
271 11) download_configs ;;
272 12) update_zshrc ;;
273 13) switch_shell ;;
274 14) log "Exiting..."; exit 0 ;;
275 *) warn "Skipping invalid option: $choice" ;;
276 esac
277 echo
278 done
279}
280
281# =============================
282# MAIN
283# =============================
284main() {
285 check_requirements
286 while true; do
287 show_menu
288 run_choices
289 read -p "Do you want to run more options? (y/n): " again
290 [[ "$again" =~ ^[Yy]$ ]] || break
291 done
292 ok "Zsh installation/configuration complete!"
293}
294
295main "$@"