Last active 22 hours ago

Revision ff76ec608a997f496e2492d61251a9ec09dcb31a

README.md Raw

Bash Script Installer for Zsh, Go, Python, GNU GCC and .NET

The "Bash Script Installer" simplifies the setup of Zsh, Go, Python, GNU GCC, and .NET on Unix-based systems, providing a user-friendly, automated installation process for developers.

ZSH

bash -c "$(curl -fsSL https://gist.githubusercontent.com/weehongkoh/e56d8161fa47e3ac8416ad8340ee3f82/raw/zsh_ubuntu.sh)"
zsh.sh Raw
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
24# This flag is for non-interactive mode.
25# Interactive menu options will override this.
26CUSTOM_CONFIG=false
27SKIP_XCLIP=false
28INSTALL_HOMEBREW=false
29
30declare -A CONFIG_FILES=(
31 [".alias"]="https://gist.githubusercontent.com/weehongkoh/72bdb76beacacf2ca3dd39a72395b9ee/raw/alias"
32 [".func"]="https://gist.githubusercontent.com/weehongkoh/72bdb76beacacf2ca3dd39a72395b9ee/raw/func"
33 [".pathrc"]="https://gist.githubusercontent.com/weehongkoh/72bdb76beacacf2ca3dd39a72395b9ee/raw/pathrc"
34 [".sourcerc"]="https://gist.githubusercontent.com/weehongkoh/72bdb76beacacf2ca3dd39a72395b9ee/raw/sourcerc"
35 [".vimrc"]="https://gist.githubusercontent.com/weehongkoh/72bdb76beacacf2ca3dd39a72395b9ee/raw/vimrc"
36 [".zshrc"]="https://gist.githubusercontent.com/weehongkoh/72bdb76beacacf2ca3dd39a72395b9ee/raw/zshrc"
37)
38
39# =============================
40# OS DETECTION
41# =============================
42detect_os() {
43 if [ -f /etc/os-release ]; then
44 . /etc/os-release
45 echo "$ID"
46 else
47 echo "unknown"
48 fi
49}
50
51# =============================
52# REQUIREMENTS
53# =============================
54check_requirements() {
55 [[ $EUID -eq 0 ]] && err "Do not run as root" && exit 1
56 command -v sudo >/dev/null || { err "sudo required"; exit 1; }
57}
58
59# =============================
60# INSTALLATION FUNCTIONS
61# =============================
62update_system() {
63 $SKIP_PACKAGES && return
64 log "Updating system..."
65 sudo apt-get update -y
66 sudo apt-get upgrade -y
67 ok "System updated"
68}
69
70install_packages() {
71 $SKIP_PACKAGES && return
72 log "Installing core packages..."
73 sudo apt-get install -y \
74 zsh git vim curl wget unzip zip build-essential xz-utils
75 ok "Packages installed"
76}
77
78set_timezone() {
79 log "Setting timezone to Asia/Singapore..."
80 sudo timedatectl set-timezone Asia/Singapore
81 ok "Timezone set to Asia/Singapore"
82}
83
84install_xclip() {
85 local os
86 os=$(detect_os)
87 [[ "$os" != "ubuntu" && "$os" != "debian" ]] && return 0
88 $SKIP_XCLIP && return 0
89 command -v xclip >/dev/null && ok "xclip already installed" && return 0
90
91 read -r -p "Install xclip? (y/N): " r
92 case "$r" in
93 [Yy]) sudo apt-get install -y xclip; ok "xclip installed" ;;
94 *) log "Skipping xclip installation" ;;
95 esac
96}
97
98configure_git() {
99 $SKIP_GIT_CONFIG && return
100 log "Configuring Git..."
101 read -p "Git name (leave empty to skip): " name
102 read -p "Git email (leave empty to skip): " email
103 [[ -n "$name" ]] && git config --global user.name "$name"
104 [[ -n "$email" ]] && git config --global user.email "$email"
105 ok "Git configured"
106}
107
108install_homebrew() {
109 ! $INSTALL_HOMEBREW && return
110 command -v brew >/dev/null && ok "Homebrew already installed" && return
111 log "Installing Homebrew..."
112 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
113 ok "Homebrew installed"
114}
115
116configure_shell() {
117 $SKIP_SHELL_CHANGE && return
118 log "Changing default shell to zsh..."
119 local zsh_path
120 zsh_path=$(command -v zsh)
121 grep -qx "$zsh_path" /etc/shells || echo "$zsh_path" | sudo tee -a /etc/shells >/dev/null
122 sudo chsh -s "$zsh_path" "$USER"
123 ok "Shell changed (requires logout/login to take effect)"
124}
125
126install_oh_my_zsh() {
127 [[ -d "$HOME/.oh-my-zsh" ]] && ok "Oh My Zsh already installed" && return
128 log "Installing Oh My Zsh..."
129 # Keep zshrc ensures we don't blow away configs if they exist
130 RUNZSH=no CHSH=no KEEP_ZSHRC=yes \
131 sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
132 ok "Oh My Zsh installed"
133}
134
135install_plugins() {
136 log "Installing plugins..."
137 local dir="${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/plugins"
138 [[ -d "$dir/zsh-autosuggestions" ]] || git clone https://github.com/zsh-users/zsh-autosuggestions "$dir/zsh-autosuggestions"
139 [[ -d "$dir/zsh-syntax-highlighting" ]] || git clone https://github.com/zsh-users/zsh-syntax-highlighting "$dir/zsh-syntax-highlighting"
140 ok "Plugins installed"
141}
142
143install_theme() {
144 log "Installing Spaceship theme..."
145 local themes="${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/themes"
146 local dir="$themes/spaceship-prompt"
147 [[ -d "$dir" ]] || git clone https://github.com/spaceship-prompt/spaceship-prompt.git "$dir" --depth=1
148 ln -sf "$dir/spaceship.zsh-theme" "$themes/spaceship.zsh-theme"
149 ok "Theme installed"
150}
151
152download_configs() {
153 # Guard clause removed so menu selection works
154 log "Downloading custom config files..."
155 local backup="$HOME/.config_backup_$(date +%Y%m%d_%H%M%S)"
156 mkdir -p "$backup"
157 for f in "${!CONFIG_FILES[@]}"; do
158 if [[ -f "$HOME/$f" ]]; then
159 cp "$HOME/$f" "$backup/"
160 fi
161 log "Fetching $f ..."
162 curl -fsSL "${CONFIG_FILES[$f]}" -o "$HOME/$f" || warn "Failed to download $f"
163 done
164 ok "Configs downloaded (Backup at $backup)"
165}
166
167update_zshrc() {
168 local zshrc="$HOME/.zshrc"
169 log "Updating .zshrc..."
170
171 # Create zshrc if missing to prevent errors
172 if [[ ! -f "$zshrc" ]]; then
173 warn ".zshrc not found, creating new one..."
174 touch "$zshrc"
175 fi
176
177 # Use || true to prevent 'set -e' from exiting if grep finds nothing
178 grep -q 'ZSH_THEME="spaceship"' "$zshrc" || sed -i 's/ZSH_THEME=".*"/ZSH_THEME="spaceship"/' "$zshrc"
179 grep -q 'zsh-autosuggestions' "$zshrc" || sed -i 's/plugins=(/plugins=(zsh-autosuggestions /' "$zshrc"
180 grep -q 'zsh-syntax-highlighting' "$zshrc" || sed -i 's/plugins=(/plugins=(zsh-syntax-highlighting /' "$zshrc"
181 ok ".zshrc updated with plugins and theme"
182}
183
184switch_shell() {
185 $SKIP_SHELL_CHANGE && return
186
187 log "Starting Zsh session..."
188 echo -e "${YELLOW}Type 'exit' to return to this installer menu.${NC}"
189 echo "----------------------------------------"
190
191 # Run zsh as a subprocess, not exec
192 zsh -l
193
194 echo "----------------------------------------"
195 ok "Returned from Zsh session"
196}
197
198# =============================
199# INTERACTIVE MENU
200# =============================
201show_menu() {
202 echo "==========================================="
203 echo "Zsh Installer - Choose what to do"
204 echo "==========================================="
205 echo " 1) Update system packages"
206 echo " 2) Install core packages (zsh, git, vim, etc.)"
207 echo " 3) Set Timezone (Asia/Singapore)"
208 echo " 4) Install xclip"
209 echo " 5) Configure Git"
210 echo " 6) Install Homebrew"
211 echo " 7) Configure shell (chsh - sets default shell)"
212 echo " 8) Install Oh My Zsh"
213 echo " 9) Install plugins (autosuggestions, syntax highlighting)"
214 echo "10) Install Spaceship theme"
215 echo "11) Download custom configs (~/.alias, .vimrc, etc.)"
216 echo "12) Update ~/.zshrc for plugins & theme"
217 echo "13) Switch to Zsh (Temporary Sub-shell)"
218 echo "14) Quit"
219 echo "==========================================="
220 echo "You can enter multiple numbers at once (e.g., 2,3,7,8)"
221}
222
223run_choices() {
224 local input
225 read -p "Select: " input
226 input="${input//,/ }" # replace commas with spaces
227
228 for choice in $input; do
229 case "$choice" in
230 1) update_system ;;
231 2) install_packages ;;
232 3) set_timezone ;;
233 4) install_xclip ;;
234 5) configure_git ;;
235 6) install_homebrew ;;
236 7) configure_shell ;;
237 8) install_oh_my_zsh ;;
238 9) install_plugins ;;
239 10) install_theme ;;
240 11) download_configs ;;
241 12) update_zshrc ;;
242 13) switch_shell ;;
243 14) log "Exiting..."; exit 0 ;;
244 *) warn "Skipping invalid option: $choice" ;;
245 esac
246 echo
247 done
248}
249
250# =============================
251# MAIN
252# =============================
253main() {
254 check_requirements
255 while true; do
256 show_menu
257 run_choices
258 read -p "Do you want to run more options? (y/n): " again
259 [[ "$again" =~ ^[Yy]$ ]] || break
260 done
261 ok "Zsh installation/configuration complete!"
262}
263
264main "$@"