Last active
November 26, 2024 11:54
-
-
Save luoling8192/883e774ddf3e6da1408d6d955912d1dc to your computer and use it in GitHub Desktop.
Ubuntu Setup Script
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| # Define colors | |
| RED='\033[0;31m' | |
| GREEN='\033[0;32m' | |
| YELLOW='\033[1;33m' | |
| NC='\033[0m' | |
| # Define package groups | |
| MIRROR="https://mirrors.tuna.tsinghua.edu.cn/ubuntu" | |
| KEYRING="/usr/share/keyrings/ubuntu-archive-keyring.gpg" | |
| SYSTEM_PACKAGES="build-essential" | |
| SHELL_PACKAGES="zsh neovim curl wget nala" | |
| UTIL_PACKAGES="neofetch eza" | |
| ZIMRC="$HOME/.zimrc" | |
| ZSHRC="$HOME/.zshrc" | |
| GITHUB_USER="luoling8192" | |
| # Helper function for confirmation | |
| confirm() { | |
| read -p "$(echo -e "${YELLOW}$1 [y/N]${NC} ")" response | |
| case "$response" in | |
| [yY][eE][sS]|[yY]) | |
| return 0 | |
| ;; | |
| *) | |
| return 1 | |
| ;; | |
| esac | |
| } | |
| # Configure apt sources | |
| configure_apt() { | |
| echo -e "${GREEN}Configuring APT sources...${NC}" | |
| cat << EOF | sudo tee /etc/apt/sources.list.d/ubuntu.sources || echo -e "${RED}Failed to configure APT sources${NC}" | |
| Types: deb | |
| URIs: $MIRROR | |
| Suites: noble noble-updates noble-backports | |
| Components: main restricted universe multiverse | |
| Signed-By: $KEYRING | |
| # Default source code mirror is commented out to improve apt update speed | |
| Types: deb-src | |
| URIs: $MIRROR | |
| Suites: noble noble-updates noble-backports | |
| Components: main restricted universe multiverse | |
| Signed-By: $KEYRING | |
| # Security updates from official source and mirror | |
| Types: deb | |
| URIs: http://security.ubuntu.com/ubuntu/ | |
| Suites: noble-security | |
| Components: main restricted universe multiverse | |
| Signed-By: $KEYRING | |
| Types: deb-src | |
| URIs: http://security.ubuntu.com/ubuntu/ | |
| Suites: noble-security | |
| Components: main restricted universe multiverse | |
| Signed-By: $KEYRING | |
| # Pre-release software sources (not recommended) | |
| # Types: deb | |
| # URIs: $MIRROR | |
| # Suites: noble-proposed | |
| # Components: main restricted universe multiverse | |
| # Signed-By: $KEYRING | |
| # Types: deb-src | |
| # URIs: $MIRROR | |
| # Suites: noble-proposed | |
| # Components: main restricted universe multiverse | |
| # Signed-By: $KEYRING | |
| EOF | |
| } | |
| # Update system packages | |
| update_system() { | |
| echo -e "${GREEN}Updating system packages...${NC}" | |
| sudo apt update -y && sudo apt upgrade -y || echo -e "${RED}Failed to update system packages${NC}" | |
| echo -e "${GREEN}Installing required packages...${NC}" | |
| sudo apt install -y $SYSTEM_PACKAGES $SHELL_PACKAGES $UTIL_PACKAGES || echo -e "${RED}Failed to install required packages${NC}" | |
| } | |
| # Configure SSH | |
| configure_ssh() { | |
| echo -e "${GREEN}Configuring SSH server...${NC}" | |
| # Enable key auth and keepalive | |
| sudo sed -i 's/#Port 22/Port 22/' /etc/ssh/sshd_config || echo -e "${RED}Failed to configure SSH port${NC}" | |
| sudo sed -i 's/#PubkeyAuthentication yes/PubkeyAuthentication yes/' /etc/ssh/sshd_config || echo -e "${RED}Failed to enable SSH key authentication${NC}" | |
| sudo sed -i 's/#ClientAliveInterval 0/ClientAliveInterval 60/' /etc/ssh/sshd_config || echo -e "${RED}Failed to set client alive interval${NC}" | |
| sudo sed -i 's/#ClientAliveCountMax 3/ClientAliveCountMax 3/' /etc/ssh/sshd_config || echo -e "${RED}Failed to set client alive count${NC}" | |
| setup_ssh_keys | |
| restart_ssh | |
| } | |
| setup_ssh_keys() { | |
| echo -e "${GREEN}Setting up SSH keys...${NC}" | |
| mkdir -p ~/.ssh || echo -e "${RED}Failed to create SSH directory${NC}" | |
| curl -fsSL https://github.com/$GITHUB_USER.keys > ~/.ssh/authorized_keys || echo -e "${RED}Failed to download SSH keys${NC}" | |
| chmod 700 ~/.ssh || echo -e "${RED}Failed to set SSH directory permissions${NC}" | |
| chmod 600 ~/.ssh/authorized_keys || echo -e "${RED}Failed to set SSH key permissions${NC}" | |
| } | |
| restart_ssh() { | |
| echo -e "${GREEN}Restarting SSH service...${NC}" | |
| sudo systemctl restart sshd || echo -e "${RED}Failed to restart SSH service${NC}" | |
| } | |
| # Configure zsh environment | |
| setup_zsh() { | |
| change_default_shell | |
| install_zim | |
| install_zim_plugins | |
| configure_shell_aliases | |
| install_atuin | |
| setup_env_vars | |
| add_command_not_found_handler | |
| } | |
| change_default_shell() { | |
| echo -e "${GREEN}Changing default shell to zsh...${NC}" | |
| sudo chsh -s $(which zsh) || echo -e "${RED}Failed to change default shell${NC}" | |
| echo -e "${GREEN}Cleaning up existing Zim installation...${NC}" | |
| rm -rf ~/.zim || echo -e "${RED}Failed to remove existing Zim installation${NC}" | |
| if confirm "Remove existing zshrc?"; then | |
| rm -f $ZSHRC || echo -e "${RED}Failed to remove existing zshrc${NC}" | |
| fi | |
| } | |
| install_zim() { | |
| reset | |
| echo -e "${GREEN}Installing Zim framework...${NC}" | |
| curl -fsSL https://raw.githubusercontent.com/zimfw/install/master/install.zsh | zsh || echo -e "${RED}Failed to install Zim framework${NC}" | |
| source $ZSHRC | |
| } | |
| install_zim_plugins() { | |
| reset | |
| echo -e "${GREEN}Installing Zim plugins...${NC}" | |
| echo "zmodule Aloxaf/fzf-tab" >> $ZIMRC || echo -e "${RED}Failed to add fzf-tab plugin${NC}" | |
| echo "zmodule romkatv/powerlevel10k --use degit" >> $ZIMRC || echo -e "${RED}Failed to add powerlevel10k plugin${NC}" | |
| zsh -c "zimfw install" || echo -e "${RED}Failed to install Zim plugins${NC}" | |
| source $ZSHRC | |
| echo -e "${GREEN}Configuring Powerlevel10k theme...${NC}" | |
| zsh -c "p10k configure" || echo -e "${RED}Failed to configure Powerlevel10k${NC}" | |
| } | |
| configure_shell_aliases() { | |
| echo -e "${GREEN}Configuring shell aliases...${NC}" | |
| cat << 'EOF' >> $ZSHRC || echo -e "${RED}Failed to configure shell aliases${NC}" | |
| # Aliases | |
| alias vim=nvim | |
| alias ls=eza | |
| alias ll="eza -lah" | |
| alias sudo="sudo " | |
| alias ip="ip -c" | |
| alias reload="source $HOME/.zshrc" | |
| alias zshrc="vim $HOME/.zshrc" | |
| # Git aliases | |
| alias gcl="git clone" | |
| alias ga="git add" | |
| alias gaa="git add -A" | |
| alias gcm="git commit -m" | |
| alias gcma="git commit -m -a" | |
| alias gp="git push" | |
| alias gpl="git pull --rebase" | |
| alias main="git switch main" | |
| EOF | |
| source $ZSHRC | |
| } | |
| install_atuin() { | |
| echo -e "${GREEN}Installing Atuin shell history manager...${NC}" | |
| # Check if atuin is already installed | |
| if command -v atuin >/dev/null 2>&1; then | |
| echo -e "${YELLOW}Atuin is already installed, skipping...${NC}" | |
| return | |
| fi | |
| if confirm "Do you want to install Atuin shell history manager?"; then | |
| bash <(curl -fsSL "https://raw.githubusercontent.com/atuinsh/atuin/main/install.sh") || echo -e "${RED}Failed to install Atuin${NC}" | |
| echo 'eval "$(atuin init zsh)"' >> $ZSHRC || echo -e "${RED}Failed to configure Atuin${NC}" | |
| source $ZSHRC | |
| if confirm "Do you want to import existing shell history?"; then | |
| zsh -c "atuin import auto" || echo -e "${RED}Failed to import shell history${NC}" | |
| fi | |
| if confirm "Do you want to sync shell history with Atuin server?"; then | |
| zsh -c "atuin sync" || echo -e "${RED}Failed to sync shell history${NC}" | |
| fi | |
| fi | |
| } | |
| setup_env_vars() { | |
| echo -e "${GREEN}Setting up environment variables...${NC}" | |
| echo 'export EDITOR="nvim"' >> $ZSHRC || echo -e "${RED}Failed to set editor${NC}" | |
| echo 'export HISTORY_IGNORE="(jetbrains*)"' >> $ZSHRC || echo -e "${RED}Failed to set history ignore${NC}" | |
| source $ZSHRC | |
| } | |
| add_command_not_found_handler() { | |
| echo -e "${GREEN}Adding command not found handler...${NC}" | |
| cat << 'EOF' >> $ZSHRC || echo -e "${RED}Failed to add command not found handler${NC}" | |
| # Handle command not found by removing from history | |
| [ ${BASH_VERSION} ] && PROMPT_COMMAND="mypromptcommand" | |
| [ ${ZSH_VERSION} ] && precmd() { mypromptcommand; } | |
| function mypromptcommand { | |
| local exit_status=$? | |
| if [ ${ZSH_VERSION} ]; then | |
| local number=$(history -1 | awk '{print $1}') | |
| elif [ ${BASH_VERSION} ]; then | |
| local number=$(history 1 | awk '{print $1}') | |
| fi | |
| if [ -n "$number" ]; then | |
| if [ $exit_status -eq 127 ] && ([ -z $HISTLASTENTRY ] || [ $HISTLASTENTRY -lt $number ]); then | |
| local RED='\033[0;31m' | |
| local NC='\033[0m' | |
| if [ ${ZSH_VERSION} ]; then | |
| local HISTORY_IGNORE="${(b)$(fc -ln $number $number)}" | |
| fc -W | |
| fc -p $HISTFILE $HISTSIZE $SAVEHIST | |
| elif [ ${BASH_VERSION} ]; then | |
| local HISTORY_IGNORE=$(history 1 | awk '{print $2}') | |
| history -d $number | |
| fi | |
| echo -e "${RED}Deleted '$HISTORY_IGNORE' from history.${NC}" | |
| else | |
| HISTLASTENTRY=$number | |
| fi | |
| fi | |
| } | |
| EOF | |
| source $ZSHRC | |
| } | |
| # Configure p10k theme | |
| configure_p10k() { | |
| echo -e "${GREEN}Configuring Powerlevel10k theme...${NC}" | |
| sed -i ' | |
| /POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS=/ { | |
| s/#.*node_version/node_version/ | |
| s/#.*go_version/go_version/ | |
| s/#.*rust_version/rust_version/ | |
| s/#.*dotnet_version/dotnet_version/ | |
| s/#.*php_version/php_version/ | |
| s/#.*laravel_version/laravel_version/ | |
| s/#.*java_version/java_version/ | |
| s/#.*terraform_version/terraform_version/ | |
| }' ~/.p10k.zsh || echo -e "${RED}Failed to configure Powerlevel10k theme${NC}" | |
| } | |
| # Setup Node environment | |
| setup_node() { | |
| install_nvm | |
| configure_nvm | |
| install_node | |
| setup_package_managers | |
| verify_node | |
| } | |
| install_nvm() { | |
| # Skip if nvm is already installed | |
| if [ -d "$HOME/.nvm" ]; then | |
| echo -e "${GREEN}NVM is already installed, skipping...${NC}" | |
| return | |
| fi | |
| echo -e "${GREEN}Installing Node Version Manager (nvm)...${NC}" | |
| curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash || echo -e "${RED}Failed to install NVM${NC}" | |
| } | |
| configure_nvm() { | |
| echo -e "${GREEN}Configuring nvm environment...${NC}" | |
| cat << 'EOF' >> $ZSHRC || echo -e "${RED}Failed to configure NVM environment${NC}" | |
| # NVM configuration | |
| export NVM_DIR="$HOME/.nvm" | |
| [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" | |
| [ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" | |
| EOF | |
| } | |
| install_node() { | |
| # Skip if node is already installed | |
| if command -v node >/dev/null 2>&1; then | |
| echo -e "${GREEN}Node.js is already installed, skipping...${NC}" | |
| return | |
| fi | |
| echo -e "${GREEN}Installing latest LTS version of Node.js...${NC}" | |
| export NVM_DIR="$HOME/.nvm" | |
| [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" | |
| zsh -c "nvm install --lts" || echo -e "${RED}Failed to install Node.js${NC}" | |
| zsh -c "nvm use --lts" || echo -e "${RED}Failed to use Node.js LTS version${NC}" | |
| } | |
| setup_package_managers() { | |
| # Skip if pnpm is already installed | |
| if command -v pnpm >/dev/null 2>&1; then | |
| echo -e "${GREEN}Package managers already setup, skipping...${NC}" | |
| return | |
| fi | |
| echo -e "${GREEN}Setting up package managers...${NC}" | |
| zsh -c "corepack enable" || echo -e "${RED}Failed to enable corepack${NC}" | |
| zsh -c "pnpm setup" || echo -e "${RED}Failed to setup pnpm${NC}" | |
| } | |
| verify_node() { | |
| echo -e "${GREEN}Verifying Node.js installation...${NC}" | |
| zsh -c "node --version" || echo -e "${RED}Failed to verify Node.js installation${NC}" | |
| zsh -c "npm --version" || echo -e "${RED}Failed to verify NPM installation${NC}" | |
| zsh -c "pnpm --version" || echo -e "${RED}Failed to verify PNPM installation${NC}" | |
| } | |
| # Setup Go environment | |
| setup_go() { | |
| # Skip if go is already installed | |
| if command -v go >/dev/null 2>&1; then | |
| echo -e "${GREEN}Go is already installed, skipping...${NC}" | |
| return | |
| fi | |
| install_go | |
| configure_go_env | |
| create_go_workspace | |
| verify_go | |
| } | |
| install_go() { | |
| echo -e "${GREEN}Downloading and installing Go...${NC}" | |
| GO_VERSION="1.21.5" | |
| GO_TAR="go${GO_VERSION}.linux-amd64.tar.gz" | |
| wget "https://go.dev/dl/${GO_TAR}" || echo -e "${RED}Failed to download Go${NC}" | |
| sudo rm -rf /usr/local/go || echo -e "${RED}Failed to remove old Go installation${NC}" | |
| sudo tar -C /usr/local -xzf ${GO_TAR} || echo -e "${RED}Failed to extract Go${NC}" | |
| rm ${GO_TAR} || echo -e "${RED}Failed to cleanup Go installer${NC}" | |
| } | |
| configure_go_env() { | |
| echo -e "${GREEN}Configuring Go environment...${NC}" | |
| cat << 'EOF' >> $ZSHRC || echo -e "${RED}Failed to configure Go environment${NC}" | |
| # Go configuration | |
| export GOROOT=/usr/local/go | |
| export GOPATH=$HOME/go | |
| export PATH=$PATH:$GOROOT/bin:$GOPATH/bin | |
| EOF | |
| export GOROOT=/usr/local/go | |
| export GOPATH=$HOME/go | |
| export PATH=$PATH:$GOROOT/bin:$GOPATH/bin | |
| } | |
| create_go_workspace() { | |
| echo -e "${GREEN}Creating Go workspace...${NC}" | |
| mkdir -p $GOPATH/{bin,src,pkg} || echo -e "${RED}Failed to create Go workspace${NC}" | |
| } | |
| verify_go() { | |
| echo -e "${GREEN}Verifying Go installation...${NC}" | |
| zsh -c "go version" || echo -e "${RED}Failed to verify Go installation${NC}" | |
| } | |
| # Execute configuration functions | |
| echo -e "${GREEN}Starting system configuration...${NC}" | |
| if confirm "Configure APT sources?"; then | |
| configure_apt | |
| fi | |
| if confirm "Update system and install packages?"; then | |
| update_system | |
| fi | |
| if confirm "Configure SSH?"; then | |
| configure_ssh | |
| fi | |
| if confirm "Setup ZSH?"; then | |
| setup_zsh | |
| fi | |
| if confirm "Configure Powerlevel10k?"; then | |
| configure_p10k | |
| fi | |
| if confirm "Setup Node.js?"; then | |
| setup_node | |
| fi | |
| if confirm "Setup Go?"; then | |
| setup_go | |
| fi | |
| echo -e "${GREEN}System configuration completed!${NC}" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment