diff --git a/.zshrc b/.zshrc index 2cbd6fe..43cfdf5 100644 --- a/.zshrc +++ b/.zshrc @@ -157,7 +157,7 @@ SAVEHIST=50000 #save upto 50,000 lines in history. oh-my-zsh default is 10, #setopt hist_ignore_all_dups # dont record duplicated entries in history during a single session alias myip="wget -qO- https://wtfismyip.com/text" # quickly show external ip address -alias l="ls --hyperlink=auto -lAhrtF" # show all except . .. , sort by recent, / at the end of folders, clickable +alias l="eza --hyperlink -lA --sort=modified --reverse --classify" # show all except . .. , sort by recent, / at the end of folders, clickable alias e="exit" alias ip="ip --color=auto" ## EZA - the better ls command @@ -184,7 +184,8 @@ cheat() { # TRAPALRM() { if command -v cmatrix &> /dev/null; then cmatrix -sb; fi } speedtest() { - curl -s https://raw.githubusercontent.com/sivel/speedtest-cli/master/speedtest.py | python3 - + setopt localoptions pipefail + curl -fsSL https://raw.githubusercontent.com/sivel/speedtest-cli/master/speedtest.py | python3 - } dadjoke() { @@ -195,9 +196,9 @@ dadjoke() { ipgeo() { # Specify ip or your ip will be used if [ "$1" ]; then - curl "http://api.db-ip.com/v2/free/$1" + curl "https://api.db-ip.com/v2/free/$1" else - curl "http://api.db-ip.com/v2/free/$(myip)" + curl "https://api.db-ip.com/v2/free/$(myip)" fi } @@ -217,7 +218,7 @@ for file in "$ZSH_CONFIGS_DIR"/*(DN); do done # Now source oh-my-zsh.sh so that any plugins added in ~/.config/zshrc/* files also get loaded -source $ZSH/oh-my-zsh.sh +source "$ZSH/oh-my-zsh.sh" # Configs that can only work after "source $ZSH/oh-my-zsh.sh", such as Aliases that depend oh-my-zsh plugins @@ -226,6 +227,6 @@ source $ZSH/oh-my-zsh.sh export FZF_DEFAULT_OPS="--extended" # Initialize zoxide (smarter cd command) -eval "$(zoxide init zsh)" +command -v zoxide &> /dev/null && eval "$(zoxide init zsh)" alias k="k -h" # show human readable file sizes, in kb, mb etc diff --git a/install.sh b/install.sh index 360918e..0264c41 100755 --- a/install.sh +++ b/install.sh @@ -1,5 +1,7 @@ #!/bin/bash +set -euo pipefail + # Save the original working directory ORIGINAL_DIR="$(pwd)" @@ -18,7 +20,8 @@ do noninteractive_flag=true ;; *) - # Handle any other arguments or provide an error message + echo "Unknown option: $arg" >&2 + exit 2 ;; esac done @@ -42,9 +45,52 @@ detect_os() { fi } +run_as_root() { + if (( EUID == 0 )); then + "$@" + elif command -v sudo &> /dev/null; then + sudo "$@" + else + echo "Error: sudo is required to run: $*" >&2 + return 1 + fi +} + +install_eza_binary() { + local archive + local binary + local target + + case $(uname -m) in + x86_64|amd64) + target="x86_64-unknown-linux-gnu" + ;; + aarch64|arm64) + target="aarch64-unknown-linux-gnu" + ;; + armv7*) + target="arm-unknown-linux-gnueabihf" + ;; + *) + echo "Error: no prebuilt eza binary is available for $(uname -m)." >&2 + return 1 + ;; + esac + + archive=$(mktemp) + binary=$(mktemp) + trap 'rm -f "${archive:-}" "${binary:-}"' EXIT + curl -fsSL "https://github.com/eza-community/eza/releases/latest/download/eza_${target}.tar.gz" -o "$archive" + tar -xOzf "$archive" ./eza > "$binary" + run_as_root install -m 755 "$binary" /usr/local/bin/eza + rm -f "$archive" "$binary" + trap - EXIT +} + # Install eza using package manager or fallback methods install_eza() { - local os=$(detect_os) + local os + os=$(detect_os) echo "Installing eza..." case $os in @@ -56,80 +102,73 @@ install_eza() { brew install eza ;; ubuntu|debian) - sudo apt-get update - if ! sudo apt-get install -y eza; then + run_as_root apt-get update + if ! run_as_root apt-get install -y eza; then echo "Package manager installation failed, attempting fallback..." - # Install cargo if it doesn't exist - if ! command -v cargo &> /dev/null; then - echo "Installing Rust and cargo..." - sudo apt-get update - sudo apt-get install -y curl build-essential - curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y - source ~/.cargo/env - fi - cargo install eza + install_eza_binary fi ;; fedora) - if ! sudo dnf install -y eza; then + if ! run_as_root dnf install -y eza; then echo "Package manager installation failed, attempting fallback..." - if command -v cargo &> /dev/null; then - cargo install eza - else - wget -qO- https://github.com/eza-community/eza/releases/latest/download/eza_x86_64-unknown-linux-gnu.tar.gz | tar xz - sudo install -m 755 eza /usr/local/bin/eza - fi + install_eza_binary fi ;; centos|rhel) - if ! sudo yum install -y eza; then + if ! run_as_root yum install -y eza; then echo "Package manager installation failed, attempting fallback..." - if command -v cargo &> /dev/null; then - cargo install eza - else - wget -qO- https://github.com/eza-community/eza/releases/latest/download/eza_x86_64-unknown-linux-gnu.tar.gz | tar xz - sudo install -m 755 eza /usr/local/bin/eza - fi + install_eza_binary fi ;; arch|manjaro) - if ! sudo pacman -Syu --noconfirm eza; then + if ! run_as_root pacman -Syu --noconfirm eza; then echo "Package manager installation failed, attempting fallback..." - wget -qO- https://github.com/eza-community/eza/releases/latest/download/eza_x86_64-unknown-linux-gnu.tar.gz | tar xz - sudo install -m 755 eza /usr/local/bin/eza + install_eza_binary fi ;; *) echo "Unsupported operating system for package manager installation, using fallback..." - wget -qO- https://github.com/eza-community/eza/releases/latest/download/eza_x86_64-unknown-linux-gnu.tar.gz | tar xz - sudo install -m 755 eza /usr/local/bin/eza + install_eza_binary ;; esac } # Helper: install zoxide if the package manager couldn't provide it +install_zoxide_binary() { + curl -sSfL https://raw.githubusercontent.com/ajeetdsouza/zoxide/main/install.sh | + sh -s -- --bin-dir /usr/local/bin --man-dir /usr/local/share/man +} + install_zoxide_fallback() { - local os=$(detect_os) + local os + os=$(detect_os) echo "Attempting fallback installation of zoxide..." case $os in + macos) + brew install zoxide + ;; fedora) - sudo dnf install -y zoxide || curl -sSfL https://raw.githubusercontent.com/ajeetdsouza/zoxide/main/install.sh | sh + run_as_root dnf install -y zoxide || install_zoxide_binary ;; centos|rhel) - if command -v dnf &> /dev/null && sudo dnf install -y zoxide; then :; else - curl -sSfL https://raw.githubusercontent.com/ajeetdsouza/zoxide/main/install.sh | sh + if command -v dnf &> /dev/null && run_as_root dnf install -y zoxide; then :; else + install_zoxide_binary fi ;; + arch|manjaro) + run_as_root pacman -S --needed --noconfirm zoxide + ;; *) - curl -sSfL https://raw.githubusercontent.com/ajeetdsouza/zoxide/main/install.sh | sh + install_zoxide_binary ;; esac } # Core: install required packages via the preferred package manager, then fall back where needed install_packages() { - local os=$(detect_os) - local base_packages="zsh git wget fontconfig zoxide autoconf" + local os + local base_packages=(zsh git wget fontconfig autoconf) + os=$(detect_os) case $os in macos) @@ -137,38 +176,46 @@ install_packages() { echo "Homebrew is not installed. Installing Homebrew..." /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" fi - brew install ${base_packages} + brew install "${base_packages[@]}" ;; ubuntu|debian) - sudo apt-get update - sudo apt-get install -y ${base_packages} + run_as_root apt-get update + run_as_root apt-get install -y "${base_packages[@]}" curl tar ;; fedora) - sudo dnf install -y ${base_packages} + run_as_root dnf install -y "${base_packages[@]}" curl tar ;; centos|rhel) - sudo yum install -y ${base_packages} + run_as_root yum install -y "${base_packages[@]}" curl tar ;; arch|manjaro) - sudo pacman -Syu --noconfirm ${base_packages} + run_as_root pacman -Syu --noconfirm "${base_packages[@]}" curl tar ;; *) - echo "Unsupported operating system. Please install ${base_packages} manually." + echo "Unsupported operating system. Please install ${base_packages[*]} manually." ;; esac # Fallbacks for any tools that are still missing after the package-manager step command -v eza &> /dev/null || install_eza command -v zoxide &> /dev/null || install_zoxide_fallback + + local command_name + for command_name in zsh git wget curl tar fc-cache eza zoxide autoconf; do + if ! command -v "$command_name" &> /dev/null; then + echo "Error: required command was not installed: $command_name" >&2 + return 1 + fi + done } # Check if required packages are installed, if not, install them -if command -v zsh &> /dev/null && command -v git &> /dev/null && command -v wget &> /dev/null && command -v fc-cache &> /dev/null && command -v eza &> /dev/null && command -v zoxide &> /dev/null && command -v autoconf &> /dev/null; then - echo -e "ZSH, Git, wget, fontconfig, eza, zoxide, and autoconf are already installed\n" +if command -v zsh &> /dev/null && command -v git &> /dev/null && command -v wget &> /dev/null && command -v curl &> /dev/null && command -v tar &> /dev/null && command -v fc-cache &> /dev/null && command -v eza &> /dev/null && command -v zoxide &> /dev/null && command -v autoconf &> /dev/null; then + echo -e "ZSH, Git, wget, curl, tar, fontconfig, eza, zoxide, and autoconf are already installed\n" else echo "Installing required packages..." install_packages - echo -e "zsh, wget, git, fontconfig, eza, zoxide, and autoconf Installed\n" + echo -e "zsh, wget, curl, tar, git, fontconfig, eza, zoxide, and autoconf installed\n" fi if [ -f ~/.gitconfig.backup ]; then @@ -181,9 +228,9 @@ fi ZSH="$HOME/.oh-my-zsh" -if mv -n ~/.zshrc ~/.zshrc-backup-$(date +"%Y-%m-%d"); then # backup .zshrc - echo -e "Backed up the current .zshrc to .zshrc-backup-date\n" -fi +zshrc_download=$(mktemp "$HOME/.zshrc.download.XXXXXX") +trap 'rm -f "$zshrc_download"' EXIT +wget -q "https://git.miomio.moe/mio/easyzsh/raw/branch/master/.zshrc" -O "$zshrc_download" # echo -e "The setup will be installed in '~/.config/ezsh'\n" # echo -e "Place your personal zshrc config files under '~/.config/ezsh/zshrc/'\n" @@ -194,20 +241,25 @@ fi # fi echo -e "Installing oh-my-zsh\n" -if [ -d $ZSH ]; then +if [ -d "$ZSH" ]; then echo -e "oh-my-zsh is already installed\n" - git -C $ZSH remote set-url origin https://github.com/ohmyzsh/ohmyzsh.git + git -C "$ZSH" remote set-url origin https://github.com/ohmyzsh/ohmyzsh.git # elif [ -d ~/.oh-my-zsh ]; then # echo -e "oh-my-zsh in already installed at '~/.oh-my-zsh'. Moving it to '$ZSH'" # export ZSH="$HOME/.config/ezsh/oh-my-zsh" # mv ~/.oh-my-zsh $ZSH # git -C $ZSH remote set-url origin https://github.com/ohmyzsh/ohmyzsh.git else - git clone --depth=1 https://github.com/ohmyzsh/ohmyzsh.git $ZSH + git clone --depth=1 https://github.com/ohmyzsh/ohmyzsh.git "$ZSH" fi -# cp -f .zshrc ~/ -wget -q "https://git.miomio.moe/mio/easyzsh/raw/branch/master/.zshrc" -O ~/.zshrc +if [ -e "$HOME/.zshrc" ] || [ -L "$HOME/.zshrc" ]; then + zshrc_backup=$(mktemp "$HOME/.zshrc.backup.$(date +"%Y%m%d-%H%M%S").XXXXXX") + cp -Pp "$HOME/.zshrc" "$zshrc_backup" + echo -e "Backed up the current .zshrc to $zshrc_backup\n" +fi +mv "$zshrc_download" "$HOME/.zshrc" +trap - EXIT # cp -f ezshrc.zsh ~/.config/ezsh/ # cp -f p10k.zsh ~/.config/ezsh/ @@ -219,28 +271,28 @@ if [ -f ~/.zcompdump ]; then mv ~/.zcompdump* ~/.cache/zsh/ fi -if [ -d $ZSH/plugins/zsh-autosuggestions ]; then - git -C $ZSH/plugins/zsh-autosuggestions pull +if [ -d "$ZSH/plugins/zsh-autosuggestions" ]; then + git -C "$ZSH/plugins/zsh-autosuggestions" pull else - git clone --depth=1 https://github.com/zsh-users/zsh-autosuggestions $ZSH/plugins/zsh-autosuggestions + git clone --depth=1 https://github.com/zsh-users/zsh-autosuggestions "$ZSH/plugins/zsh-autosuggestions" fi -if [ -d $ZSH/custom/plugins/zsh-syntax-highlighting ]; then - git -C $ZSH/custom/plugins/zsh-syntax-highlighting pull +if [ -d "$ZSH/custom/plugins/zsh-syntax-highlighting" ]; then + git -C "$ZSH/custom/plugins/zsh-syntax-highlighting" pull else - git clone --depth=1 https://github.com/zsh-users/zsh-syntax-highlighting.git $ZSH/custom/plugins/zsh-syntax-highlighting + git clone --depth=1 https://github.com/zsh-users/zsh-syntax-highlighting.git "$ZSH/custom/plugins/zsh-syntax-highlighting" fi -if [ -d $ZSH/custom/plugins/zsh-completions ]; then - git -C $ZSH/custom/plugins/zsh-completions pull +if [ -d "$ZSH/custom/plugins/zsh-completions" ]; then + git -C "$ZSH/custom/plugins/zsh-completions" pull else - git clone --depth=1 https://github.com/zsh-users/zsh-completions $ZSH/custom/plugins/zsh-completions + git clone --depth=1 https://github.com/zsh-users/zsh-completions "$ZSH/custom/plugins/zsh-completions" fi -if [ -d $ZSH/custom/plugins/zsh-history-substring-search ]; then - git -C $ZSH/custom/plugins/zsh-history-substring-search pull +if [ -d "$ZSH/custom/plugins/zsh-history-substring-search" ]; then + git -C "$ZSH/custom/plugins/zsh-history-substring-search" pull else - git clone --depth=1 https://github.com/zsh-users/zsh-history-substring-search $ZSH/custom/plugins/zsh-history-substring-search + git clone --depth=1 https://github.com/zsh-users/zsh-history-substring-search "$ZSH/custom/plugins/zsh-history-substring-search" fi @@ -274,12 +326,12 @@ fi fc-cache -fv ~/.fonts -if [ -d $ZSH/custom/themes/powerlevel10k ]; then - git -C $ZSH/custom/themes/powerlevel10k pull +if [ -d "$ZSH/custom/themes/powerlevel10k" ]; then + git -C "$ZSH/custom/themes/powerlevel10k" pull else - git clone --depth=1 https://github.com/romkatv/powerlevel10k.git $ZSH/custom/themes/powerlevel10k + git clone --depth=1 https://github.com/romkatv/powerlevel10k.git "$ZSH/custom/themes/powerlevel10k" fi -curl -s https://git.miomio.moe/mio/easyzsh/raw/branch/master/patch.sh | bash -s p10k +curl -fsSL https://git.miomio.moe/mio/easyzsh/raw/branch/master/patch.sh | bash -s -- p10k if [ -d ~/.fzf ]; then git -C ~/.fzf pull @@ -289,16 +341,16 @@ else ~/.fzf/install --all --key-bindings --completion --no-update-rc fi -if [ -d $ZSH/custom/plugins/k ]; then - git -C $ZSH/custom/plugins/k pull +if [ -d "$ZSH/custom/plugins/k" ]; then + git -C "$ZSH/custom/plugins/k" pull else - git clone --depth 1 https://github.com/supercrabtree/k $ZSH/custom/plugins/k + git clone --depth 1 https://github.com/supercrabtree/k "$ZSH/custom/plugins/k" fi -if [ -d $ZSH/custom/plugins/fzf-tab ]; then - git -C $ZSH/custom/plugins/fzf-tab pull +if [ -d "$ZSH/custom/plugins/fzf-tab" ]; then + git -C "$ZSH/custom/plugins/fzf-tab" pull else - git clone --depth 1 https://github.com/Aloxaf/fzf-tab $ZSH/custom/plugins/fzf-tab + git clone --depth 1 https://github.com/Aloxaf/fzf-tab "$ZSH/custom/plugins/fzf-tab" fi # Import existing z data into zoxide if available @@ -342,7 +394,7 @@ if [ "$cp_hist_flag" = true ]; then wget -q --show-progress https://gist.githubusercontent.com/muendelezaji/c14722ab66b505a49861b8a74e52b274/raw/49f0fb7f661bdf794742257f58950d209dd6cb62/bash-to-zsh-hist.py cat ~/.bash_history | python3 bash-to-zsh-hist.py >> ~/.zsh_history else - echo "Python is not installed, can't copy bash_history to zsh_history\n" + printf "Python is not installed, can't copy bash_history to zsh_history\n" fi fi else @@ -351,18 +403,18 @@ fi if [ "$noninteractive_flag" = true ]; then echo -e "Installation complete, exit terminal and enter a new zsh session\n" - echo -e "Make sure to change zsh to default shell by running: chsh -s $(which zsh)" + echo -e "Make sure to change zsh to default shell by running: chsh -s $(command -v zsh)" echo -e "In a new zsh session manually run: build-fzf-tab-module" else # source ~/.zshrc - echo -e "\nSudo access is needed to change default shell\n" + echo -e "\nAdministrator access is needed to change the default shell\n" - if sudo chsh -s $(which zsh) $USER && /bin/zsh -i -c 'omz update'; then + if run_as_root chsh -s "$(command -v zsh)" "${USER:-$(id -un)}" && /bin/zsh -i -c 'omz update'; then echo -e "Installation complete, exit terminal and enter a new zsh session" echo -e "In a new zsh session manually run: build-fzf-tab-module" else echo -e "Something is wrong" - + exit 1 fi fi diff --git a/install/fnm.sh b/install/fnm.sh deleted file mode 100644 index 4fea74a..0000000 --- a/install/fnm.sh +++ /dev/null @@ -1,230 +0,0 @@ -#!/bin/bash - -set -e - -RELEASE="latest" -OS="$(uname -s)" - -case "${OS}" in - MINGW* | Win*) OS="Windows" ;; -esac - -if [ -d "$HOME/.fnm" ]; then - INSTALL_DIR="$HOME/.fnm" -elif [ -n "$XDG_DATA_HOME" ]; then - INSTALL_DIR="$XDG_DATA_HOME/fnm" -elif [ "$OS" = "Darwin" ]; then - INSTALL_DIR="$HOME/Library/Application Support/fnm" -else - INSTALL_DIR="$HOME/.local/share/fnm" -fi - -# Parse Flags -parse_args() { - while [[ $# -gt 0 ]]; do - key="$1" - - case $key in - -d | --install-dir) - INSTALL_DIR="$2" - shift # past argument - shift # past value - ;; - -s | --skip-shell) - SKIP_SHELL="true" - shift # past argument - ;; - --force-install | --force-no-brew) - echo "\`--force-install\`: I hope you know what you're doing." >&2 - FORCE_INSTALL="true" - shift - ;; - -r | --release) - RELEASE="$2" - shift # past release argument - shift # past release value - ;; - *) - echo "Unrecognized argument $key" - exit 1 - ;; - esac - done -} - -set_filename() { - if [ "$OS" = "Linux" ]; then - # Based on https://stackoverflow.com/a/45125525 - case "$(uname -m)" in - arm | armv7*) - FILENAME="fnm-arm32" - ;; - aarch* | armv8*) - FILENAME="fnm-arm64" - ;; - *) - FILENAME="fnm-linux" - esac - elif [ "$OS" = "Darwin" ] && [ "$FORCE_INSTALL" = "true" ]; then - FILENAME="fnm-macos" - USE_HOMEBREW="false" - echo "Downloading the latest fnm binary from GitHub..." - echo " Pro tip: it's easier to use Homebrew for managing fnm in macOS." - echo " Remove the \`--force-no-brew\` so it will be easy to upgrade." - elif [ "$OS" = "Darwin" ]; then - USE_HOMEBREW="true" - echo "Downloading fnm using Homebrew..." - elif [ "$OS" = "Windows" ] ; then - FILENAME="fnm-windows" - echo "Downloading the latest fnm binary from GitHub..." - else - echo "OS $OS is not supported." - echo "If you think that's a bug - please file an issue to https://github.com/Schniz/fnm/issues" - exit 1 - fi -} - -download_fnm() { - if [ "$USE_HOMEBREW" = "true" ]; then - brew install fnm - else - if [ "$RELEASE" = "latest" ]; then - URL="https://github.com/Schniz/fnm/releases/latest/download/$FILENAME.zip" - else - URL="https://github.com/Schniz/fnm/releases/download/$RELEASE/$FILENAME.zip" - fi - - DOWNLOAD_DIR=$(mktemp -d) - - echo "Downloading $URL..." - - mkdir -p "$INSTALL_DIR" &>/dev/null - - if ! curl --progress-bar --fail -L "$URL" -o "$DOWNLOAD_DIR/$FILENAME.zip"; then - echo "Download failed. Check that the release/filename are correct." - exit 1 - fi - - unzip -q "$DOWNLOAD_DIR/$FILENAME.zip" -d "$DOWNLOAD_DIR" - - if [ -f "$DOWNLOAD_DIR/fnm" ]; then - mv "$DOWNLOAD_DIR/fnm" "$INSTALL_DIR/fnm" - else - mv "$DOWNLOAD_DIR/$FILENAME/fnm" "$INSTALL_DIR/fnm" - fi - - chmod u+x "$INSTALL_DIR/fnm" - fi -} - -check_dependencies() { - echo "Checking dependencies for the installation script..." - - echo -n "Checking availability of curl... " - if hash curl 2>/dev/null; then - echo "OK!" - else - echo "Missing!" - SHOULD_EXIT="true" - fi - - echo -n "Checking availability of unzip... " - if hash unzip 2>/dev/null; then - echo "OK!" - else - echo "Missing!" - SHOULD_EXIT="true" - fi - - if [ "$USE_HOMEBREW" = "true" ]; then - echo -n "Checking availability of Homebrew (brew)... " - if hash brew 2>/dev/null; then - echo "OK!" - else - echo "Missing!" - SHOULD_EXIT="true" - fi - fi - - if [ "$SHOULD_EXIT" = "true" ]; then - echo "Not installing fnm due to missing dependencies." - exit 1 - fi -} - -ensure_containing_dir_exists() { - local CONTAINING_DIR - CONTAINING_DIR="$(dirname "$1")" - if [ ! -d "$CONTAINING_DIR" ]; then - echo " >> Creating directory $CONTAINING_DIR" - mkdir -p "$CONTAINING_DIR" - fi -} - -setup_shell() { - CURRENT_SHELL="$(basename "$SHELL")" - - if [ "$CURRENT_SHELL" = "zsh" ]; then - CONF_FILE=${ZDOTDIR:-$HOME}/.zshrc - ensure_containing_dir_exists "$CONF_FILE" - echo "Installing for Zsh. Appending the following to $CONF_FILE:" - { - echo '' - echo '# fnm' - echo 'FNM_PATH="'"$INSTALL_DIR"'"' - echo 'if [ -d "$FNM_PATH" ]; then' - echo ' export PATH="'$INSTALL_DIR':$PATH"' - echo ' eval "`fnm env`"' - echo 'fi' - } | tee -a "$CONF_FILE" - - elif [ "$CURRENT_SHELL" = "fish" ]; then - CONF_FILE=$HOME/.config/fish/conf.d/fnm.fish - ensure_containing_dir_exists "$CONF_FILE" - echo "Installing for Fish. Appending the following to $CONF_FILE:" - { - echo '' - echo '# fnm' - echo 'set FNM_PATH "'"$INSTALL_DIR"'"' - echo 'if [ -d "$FNM_PATH" ]' - echo ' set PATH "$FNM_PATH" $PATH' - echo ' fnm env | source' - echo 'end' - } | tee -a "$CONF_FILE" - - elif [ "$CURRENT_SHELL" = "bash" ]; then - if [ "$OS" = "Darwin" ]; then - CONF_FILE=$HOME/.profile - else - CONF_FILE=$HOME/.bashrc - fi - ensure_containing_dir_exists "$CONF_FILE" - echo "Installing for Bash. Appending the following to $CONF_FILE:" - { - echo '' - echo '# fnm' - echo 'FNM_PATH="'"$INSTALL_DIR"'"' - echo 'if [ -d "$FNM_PATH" ]; then' - echo ' export PATH="$FNM_PATH:$PATH"' - echo ' eval "`fnm env`"' - echo 'fi' - } | tee -a "$CONF_FILE" - - else - echo "Could not infer shell type. Please set up manually." - exit 1 - fi - - echo "" - echo "In order to apply the changes, open a new terminal or run the following command:" - echo "" - echo " source $CONF_FILE" -} - -parse_args "$@" -set_filename -check_dependencies -download_fnm -if [ "$SKIP_SHELL" != "true" ]; then - setup_shell -fi \ No newline at end of file diff --git a/install_fnm.sh b/install_fnm.sh index ad49d01..8013966 100755 --- a/install_fnm.sh +++ b/install_fnm.sh @@ -1,7 +1,6 @@ #!/bin/bash -# Save the original working directory -ORIGINAL_DIR="$(pwd)" +set -euo pipefail # Function to detect the operating system detect_os() { @@ -15,50 +14,71 @@ detect_os() { fi } +run_as_root() { + if (( EUID == 0 )); then + "$@" + elif command -v sudo &> /dev/null; then + sudo "$@" + else + echo "Error: sudo is required to install unzip." >&2 + exit 1 + fi +} + +install_unzip() { + command -v unzip &> /dev/null && return + + echo "Installing required dependency: unzip" + case $(detect_os) in + ubuntu|debian) + run_as_root apt-get update + run_as_root apt-get install -y unzip + ;; + fedora) + run_as_root dnf install -y unzip + ;; + centos|rhel) + if command -v dnf &> /dev/null; then + run_as_root dnf install -y unzip + else + run_as_root yum install -y unzip + fi + ;; + arch|manjaro) + run_as_root pacman -S --needed --noconfirm unzip + ;; + *) + echo "Error: unzip is required. Install it with your package manager and retry." >&2 + exit 1 + ;; + esac +} + # Install fnm (Fast Node Manager) if it is not already installed if command -v fnm &> /dev/null; then echo -e "fnm is already installed\n" fnm --version else echo -e "Installing fnm (Fast Node Manager)\n" - - os=$(detect_os) - - case $os in - macos) - # Try homebrew first on macOS - if command -v brew &> /dev/null; then - echo "Installing fnm via Homebrew..." - brew install fnm - else - echo "Installing fnm via official installer..." - curl -fsSL https://git.miomio.moe/mio/easyzsh/raw/branch/master/install/fnm.sh | bash - fi - ;; - ubuntu|debian) - # Use the official installer for Linux - echo "Installing fnm via official installer..." - curl -fsSL https://git.miomio.moe/mio/easyzsh/raw/branch/master/install/fnm.sh | bash - ;; - fedora|centos|rhel) - # Use the official installer for RHEL-based distros - echo "Installing fnm via official installer..." - curl -fsSL https://git.miomio.moe/mio/easyzsh/raw/branch/master/install/fnm.sh | bash - ;; - arch|manjaro) - # Use the official installer for Arch-based distros - echo "Installing fnm via official installer..." - curl -fsSL https://git.miomio.moe/mio/easyzsh/raw/branch/master/install/fnm.sh | bash - ;; - *) - echo "Using official installer for unknown OS..." - curl -fsSL https://git.miomio.moe/mio/easyzsh/raw/branch/master/install/fnm.sh | bash - ;; - esac - # Load fnm for the remainder of this script - export PATH="$HOME/.local/share/fnm:$PATH" - eval "$(fnm env --use-on-cd)" + os=$(detect_os) + + if [[ "$os" == "macos" ]] && command -v brew &> /dev/null; then + echo "Installing fnm via Homebrew..." + brew install fnm + else + install_unzip + install_dir="${XDG_DATA_HOME:-$HOME/.local/share}/fnm" + installer_args=(--install-dir "$install_dir" --skip-shell) + [[ "$os" == "macos" ]] && installer_args+=(--force-install) + + echo "Installing fnm via official installer..." + curl -fsSL https://fnm.vercel.app/install | bash -s -- "${installer_args[@]}" + export PATH="$install_dir:$PATH" + fi + + command -v fnm &> /dev/null + eval "$(fnm env --use-on-cd --shell bash)" fi # OPTIONAL: Install the latest LTS version of Node.js @@ -69,17 +89,13 @@ fi # fnm default lts-latest # Apply the fnm zsh configuration patch (downloads zshrc/fnm.zsh to ~/.config/zshrc/fnm.zsh) -curl -fsSL https://git.miomio.moe/mio/easyzsh/raw/branch/master/patch.sh | bash -s fnm +curl -fsSL https://git.miomio.moe/mio/easyzsh/raw/branch/master/patch.sh | bash -s -- fnm echo -e "\nfnm installation completed!" echo -e "To start using fnm, restart your terminal or run: source ~/.zshrc" echo -e "\nUseful fnm commands:" echo -e " fnm install --lts # Install latest LTS Node.js" -echo -e " fnm install 18 # Install Node.js v18" -echo -e " fnm use 18 # Use Node.js v18" -echo -e " fnm default 18 # Set Node.js v18 as default" +echo -e " fnm use lts-latest # Use the latest LTS release" +echo -e " fnm default lts-latest # Set the latest LTS as default" echo -e " fnm list # List installed versions" echo -e " fnm list-remote # List available versions" - -# Restore original working directory -cd "$ORIGINAL_DIR" \ No newline at end of file diff --git a/install_merlin_worker.sh b/install_merlin_worker.sh index 78afb59..f6f46f6 100755 --- a/install_merlin_worker.sh +++ b/install_merlin_worker.sh @@ -1,10 +1,10 @@ #!/bin/bash -# Exit on any error -set -e +# Exit if either side of a download pipeline fails +set -euo pipefail # Download and execute the patch script -if ! curl -s https://git.miomio.moe/mio/easyzsh/raw/branch/master/patch.sh | bash -s merlin_worker; then +if ! curl -fsSL https://git.miomio.moe/mio/easyzsh/raw/branch/master/patch.sh | bash -s -- merlin_worker; then echo "Error: Failed to download or execute patch script" exit 1 fi @@ -12,7 +12,7 @@ fi # Check if ~/.bashrc exists and contains PYTHONPATH export if [ -f "$HOME/.bashrc" ]; then # Extract PYTHONPATH from ~/.bashrc (look for export PYTHONPATH=...) - BASHRC_PYTHONPATH=$(grep -E "^export PYTHONPATH=" "$HOME/.bashrc" | tail -1) + BASHRC_PYTHONPATH=$(grep -E "^export PYTHONPATH=" "$HOME/.bashrc" | tail -1 || true) if [ -n "$BASHRC_PYTHONPATH" ]; then echo "Found PYTHONPATH in ~/.bashrc: $BASHRC_PYTHONPATH" @@ -46,5 +46,5 @@ if [ -f "$HOME/.bashrc" ]; then echo "No PYTHONPATH export found in ~/.bashrc" fi else - echo "~/.bashrc not found" + echo "$HOME/.bashrc not found" fi diff --git a/install_nvm.sh b/install_nvm.sh index e3e7c29..fbbe99d 100755 --- a/install_nvm.sh +++ b/install_nvm.sh @@ -1,7 +1,9 @@ #!/bin/bash -# Save the original working directory -ORIGINAL_DIR="$(pwd)" +set -euo pipefail + +NVM_VERSION="v0.40.4" +export NVM_DIR="${NVM_DIR:-$HOME/.nvm}" # Install nvm (Node Version Manager) if it is not already installed if command -v nvm &> /dev/null; then @@ -9,19 +11,15 @@ if command -v nvm &> /dev/null; then else echo -e "Installing nvm (Node Version Manager)\n" # Using the official install script (https://github.com/nvm-sh/nvm) - curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash + curl -fsSL "https://raw.githubusercontent.com/nvm-sh/nvm/${NVM_VERSION}/install.sh" | bash # Load nvm for the remainder of this script - export NVM_DIR="${XDG_CONFIG_HOME:-$HOME/.nvm}" [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" + command -v nvm &> /dev/null fi -# OPTIONAL: Install the latest LTS version of Node.js -# Uncomment the following line if you would like to automatically install it +# Install the latest LTS version of Node.js nvm install --lts -# Apply the "basic" zsh configuration patch (downloads zshrc/basic.zsh to ~/.config/zshrc/basic.zsh) -curl -s https://git.miomio.moe/mio/easyzsh/raw/branch/master/patch.sh | bash -s nvm - -# Restore original working directory -cd "$ORIGINAL_DIR" +# Apply the nvm zsh configuration patch +curl -fsSL https://git.miomio.moe/mio/easyzsh/raw/branch/master/patch.sh | bash -s -- nvm diff --git a/install_pyenv.sh b/install_pyenv.sh index 81e398e..92c5241 100755 --- a/install_pyenv.sh +++ b/install_pyenv.sh @@ -1,7 +1,6 @@ #!/bin/bash -# Save the original working directory -ORIGINAL_DIR="$(pwd)" +set -euo pipefail # Install pyenv (Python Version Manager) if it is not already installed if command -v pyenv &> /dev/null; then @@ -15,6 +14,7 @@ else export PYENV_ROOT="$HOME/.pyenv" [[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH" eval "$(pyenv init - bash)" + command -v pyenv &> /dev/null fi # OPTIONAL: Install the latest stable version of Python @@ -22,7 +22,4 @@ fi # pyenv install 3.12.0 && pyenv global 3.12.0 # Apply the pyenv zsh configuration patch (downloads zshrc/pyenv.zsh to ~/.config/zshrc/pyenv.zsh) -curl -s https://git.miomio.moe/mio/easyzsh/raw/branch/master/patch.sh | bash -s pyenv - -# Restore original working directory -cd "$ORIGINAL_DIR" +curl -fsSL https://git.miomio.moe/mio/easyzsh/raw/branch/master/patch.sh | bash -s -- pyenv diff --git a/patch.sh b/patch.sh index 433398e..3d156ce 100644 --- a/patch.sh +++ b/patch.sh @@ -1,16 +1,30 @@ #!/bin/bash +set -euo pipefail + BASE_URL="https://git.miomio.moe/mio/easyzsh/raw/branch/master/zshrc" ZSH_CONFIGS_DIR="$HOME/.config/zshrc" -mkdir -p $ZSH_CONFIGS_DIR +mkdir -p "$ZSH_CONFIGS_DIR" if [ "$#" -gt 0 ]; then for arg in "$@"; do - if ! wget "${BASE_URL}/${arg}.zsh" -O "${ZSH_CONFIGS_DIR}/${arg}.zsh"; then + if [[ -z "$arg" || "$arg" == *[![:alnum:]_-]* ]]; then + echo "Invalid config name: $arg" >&2 + exit 1 + fi + + destination="${ZSH_CONFIGS_DIR}/${arg}.zsh" + temporary=$(mktemp "$HOME/.config/.easyzsh-${arg}.XXXXXX") + trap 'rm -f "$temporary"' EXIT + + if ! curl -fsSL "${BASE_URL}/${arg}.zsh" -o "$temporary"; then echo "Failed to download ${arg}.zsh from ${BASE_URL}" exit 1 fi + + mv "$temporary" "$destination" + trap - EXIT done else echo "No arguments provided. Please specify the config files to download." diff --git a/tests/installers.sh b/tests/installers.sh new file mode 100755 index 0000000..c421e9e --- /dev/null +++ b/tests/installers.sh @@ -0,0 +1,85 @@ +#!/usr/bin/env bash + +set -euo pipefail + +ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd) +TEMP_DIR=$(mktemp -d) +trap 'rm -rf "$TEMP_DIR"' EXIT + +fail() { + echo "FAIL: $*" >&2 + exit 1 +} + +assert_download_failure_is_reported() { + local home="$TEMP_DIR/home-${1%.sh}" + mkdir -p "$home" + + if HOME="$home" PATH="$TEMP_DIR/bin:/usr/bin:/bin" /bin/bash "$ROOT/$1" >"$home/output" 2>&1; then + fail "$1 returned success after curl failed" + fi +} + +mkdir -p "$TEMP_DIR/bin" +ln -s /usr/bin/false "$TEMP_DIR/bin/curl" +ln -s /usr/bin/true "$TEMP_DIR/bin/unzip" + +for script in install_fnm.sh install_nvm.sh install_pyenv.sh install_merlin_worker.sh; do + assert_download_failure_is_reported "$script" +done + +patch_home="$TEMP_DIR/patch-home" +mkdir -p "$patch_home/.config/zshrc" +cp "$ROOT/README.md" "$patch_home/.config/zshrc/missing.zsh" +if HOME="$patch_home" PATH="$TEMP_DIR/bin:/usr/bin:/bin" /bin/bash "$ROOT/patch.sh" missing >/dev/null 2>&1; then + fail "patch.sh returned success after curl failed" +fi +cmp -s "$ROOT/README.md" "$patch_home/.config/zshrc/missing.zsh" || + fail "patch.sh replaced an existing config after curl failed" + +if HOME="$patch_home" PATH="$TEMP_DIR/bin:/usr/bin:/bin" /bin/bash "$ROOT/patch.sh" ../invalid >/dev/null 2>&1; then + fail "patch.sh accepted an unsafe config name" +fi + +main_bin="$TEMP_DIR/main-bin" +main_home="$TEMP_DIR/main-home" +mkdir -p "$main_bin" "$main_home" +for command_name in zsh git curl tar fc-cache eza zoxide autoconf; do + ln -s /usr/bin/true "$main_bin/$command_name" +done +ln -s /usr/bin/false "$main_bin/wget" +cp "$ROOT/README.md" "$main_home/.zshrc" +if HOME="$main_home" PATH="$main_bin:/usr/bin:/bin" /bin/bash "$ROOT/install.sh" --non-interactive >/dev/null 2>&1; then + fail "install.sh returned success after the zshrc download failed" +fi +cmp -s "$ROOT/README.md" "$main_home/.zshrc" || + fail "install.sh replaced .zshrc after its download failed" + +fnm_home="$TEMP_DIR/fnm-home" +mkdir -p "$fnm_home/.local/share/fnm" +ln -s /usr/bin/true "$fnm_home/.local/share/fnm/fnm" +HOME="$fnm_home" PATH=/usr/bin:/bin zsh -c 'source "$1"; command -v fnm >/dev/null' zsh "$ROOT/zshrc/fnm.zsh" || + fail "fnm is not restored to PATH in a new Zsh session" + +for script in "$ROOT"/*.sh; do + bash -n "$script" +done + +for config in "$ROOT/.zshrc" "$ROOT"/zshrc/*.zsh; do + zsh -n "$config" +done + +grep -q 'NVM_VERSION="v0.40.4"' "$ROOT/install_nvm.sh" || fail "nvm version is stale" +grep -q 'apt-get install -y unzip' "$ROOT/install_fnm.sh" || fail "Ubuntu unzip installation is missing" +grep -q 'tail -1 || true' "$ROOT/install_merlin_worker.sh" || fail "a missing PYTHONPATH remains fatal" +grep -Fq 'mktemp "$HOME/.zshrc.download.' "$ROOT/install.sh" || fail ".zshrc is not downloaded on its target filesystem" +grep -Fq 'mktemp "$HOME/.config/.easyzsh-' "$ROOT/patch.sh" || fail "patch downloads can be sourced while incomplete" +grep -Fq '"$ZSH_CONFIGS_DIR"/*(DN)' "$ROOT/.zshrc" || fail "existing extensionless Zsh configs are ignored" +grep -Fq 'cp -Pp "$HOME/.zshrc"' "$ROOT/install.sh" || fail ".zshrc symlinks are not preserved in backups" +grep -Fq '[ -L "$HOME/.zshrc" ]' "$ROOT/install.sh" || fail "broken .zshrc symlinks are not backed up" +[[ ! -e "$ROOT/install/fnm.sh" ]] || fail "vendored fnm installer still exists" +if grep -Eq '^[[:space:]]*export MLX_USER_TOKEN=' "$ROOT"/zshrc/*.zsh; then + fail "a static MLX user token remains" +fi + +echo "installer checks passed" diff --git a/zshrc/fnm.zsh b/zshrc/fnm.zsh index 8242b3b..4bc6c25 100644 --- a/zshrc/fnm.zsh +++ b/zshrc/fnm.zsh @@ -1,8 +1,6 @@ -# fnm (Fast Node Manager) configuration -# https://github.com/Schniz/fnm - -FNM_PATH="$HOME/.local/share/fnm" -if [ -d "$FNM_PATH" ]; then - export PATH="$HOME/.local/share/fnm:$PATH" - eval "$(fnm env --use-on-cd --shell zsh)" +# fnm (Fast Node Manager) +FNM_PATH="${XDG_DATA_HOME:-$HOME/.local/share}/fnm" +[[ -d "$FNM_PATH" ]] && export PATH="$FNM_PATH:$PATH" +if command -v fnm &> /dev/null; then + eval "$(fnm env --use-on-cd --shell zsh)" fi diff --git a/zshrc/merlin_devbox.zsh b/zshrc/merlin_devbox.zsh index 1a61e97..aeb0dcb 100644 --- a/zshrc/merlin_devbox.zsh +++ b/zshrc/merlin_devbox.zsh @@ -14,14 +14,15 @@ -# Set cur_dir before sourcing so prep_env.sh uses the correct path -export cur_dir="/workspace/vscode" - -# Patch prep_env.sh for zsh compatibility before sourcing -source <(sed -e 's/^shopt -s histappend$/[[ -n "${BASH_VERSION}" ]] \&\& shopt -s histappend/' \ - -e 's/\${!\([^}]*\)}/${(P)\1}/g' \ - -e 's/cur_dir="\$(cd "\$(dirname "\$0")" && pwd)"/# cur_dir already set/g' \ - /workspace/mlx/../vscode/prep_env.sh) +_prep_env="/workspace/vscode/prep_env.sh" +if [[ -r "$_prep_env" ]]; then + export cur_dir="/workspace/vscode" + source <(sed -e 's/^shopt -s histappend$/[[ -n "${BASH_VERSION}" ]] \&\& shopt -s histappend/' \ + -e 's/\${!\([^}]*\)}/${(P)\1}/g' \ + -e 's/cur_dir="\$(cd "\$(dirname "\$0")" && pwd)"/# cur_dir already set/g' \ + "$_prep_env") +fi +unset _prep_env # sh -c /opt/tiger/mlx_deploy/greeting.sh @@ -33,7 +34,7 @@ if [ -f "/opt/tiger/rh2_bashrc" ]; then source /opt/tiger/rh2_bashrc fi -. "$HOME/.cargo/env" +[[ -r "$HOME/.cargo/env" ]] && . "$HOME/.cargo/env" # huggingface proxy export HF_NETWORK_PROXY=http://huggingface-proxy-sg.byted.org @@ -47,10 +48,10 @@ alias hf_mirror_external='export HF_ENDPOINT=$HF_MIRROR_EXTERNAL' # http proxy export HTTP_PROXY=http://sys-proxy-rd-relay.byted.org:8118 export HTTPS_PROXY=http://sys-proxy-rd-relay.byted.org:8118 -export NO_PROXY=byted.org,bytedance.net,10.*.*.*,127.*.*.* +export NO_PROXY='byted.org,bytedance.net,10.*.*.*,127.*.*.*' export http_proxy=http://sys-proxy-rd-relay.byted.org:8118 export https_proxy=http://sys-proxy-rd-relay.byted.org:8118 -export no_proxy=byted.org,bytedance.net,10.*.*.*,127.*.*.* +export no_proxy='byted.org,bytedance.net,10.*.*.*,127.*.*.*' alias proxy_on='export http_proxy=http://sys-proxy-rd-relay.byted.org:8118; export https_proxy=http://sys-proxy-rd-relay.byted.org:8118; export no_proxy=byted.org,bytedance.net,10.*.*.*,127.*.*.*; export HTTP_PROXY=http://sys-proxy-rd-relay.byted.org:8118; export HTTPS_PROXY=http://sys-proxy-rd-relay.byted.org:8118; export NO_PROXY=byted.org,bytedance.net,10.*.*.*,127.*.*.*' alias proxy_off='unset http_proxy; unset https_proxy; unset no_proxy; unset HTTP_PROXY; unset HTTPS_PROXY; unset NO_PROXY' diff --git a/zshrc/merlin_worker.zsh b/zshrc/merlin_worker.zsh index 98a37e9..82b2ff8 100644 --- a/zshrc/merlin_worker.zsh +++ b/zshrc/merlin_worker.zsh @@ -6,7 +6,6 @@ alias stderr='tail -f /var/log/tiger/stderr' # Essential environment variables export MERLIN_PROFILING_HDFS_DIR='hdfs://haruna/home/byte_merlin_profiling/' export RH2_ENV_JSON=/opt/tiger/rh2/env_json -export MLX_USER_TOKEN=bd2a3f1b71d54ab497f13f2eefc4f5bc export RH2_TENSORBOARD_HDFS=hdfs://haruna/home/byte_aml_platform/public/rh2_prod/8b6d8490dc2904e0/tensorboard/20250527/903e5003c90ff1dc/arnold_trial/46714689 export SPARK_HOME=/opt/tiger/spark_deploy/spark-3.2/spark-stable export PATH=/opt/common_tools:/opt/tiger/typhoon-blade:/usr/lib/x86_64-linux-gnu/openmpi/bin:/usr/local/cuda/bin:/home/tiger/system_op/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/tiger/arnold/arnold_entrypoint/tools:/opt/tiger/arnold/hdfs_client:/opt/tiger/yarn_deploy/hadoop/bin:/opt/tiger/yarn_deploy/hive/bin:/home/tiger/.local/bin:/opt/tiger/nastk/bin:/python:/opt/tiger/mlx_deploy/bin @@ -29,10 +28,10 @@ alias hf_mirror_external='export HF_ENDPOINT=$HF_MIRROR_EXTERNAL' export HF_ENDPOINT=http://huggingface-proxy-sg.byted.org export HTTP_PROXY=http://sys-proxy-rd-relay.byted.org:8118 export HTTPS_PROXY=http://sys-proxy-rd-relay.byted.org:8118 -export NO_PROXY=byted.org,bytedance.net,10.*.*.*,127.*.*.* +export NO_PROXY='byted.org,bytedance.net,10.*.*.*,127.*.*.*' export http_proxy=http://sys-proxy-rd-relay.byted.org:8118 export https_proxy=http://sys-proxy-rd-relay.byted.org:8118 -export no_proxy=byted.org,bytedance.net,10.*.*.*,127.*.*.* +export no_proxy='byted.org,bytedance.net,10.*.*.*,127.*.*.*' alias proxy_on='export http_proxy=http://sys-proxy-rd-relay.byted.org:8118; export https_proxy=http://sys-proxy-rd-relay.byted.org:8118; export no_proxy=byted.org,bytedance.net,10.*.*.*,127.*.*.*; export HTTP_PROXY=http://sys-proxy-rd-relay.byted.org:8118; export HTTPS_PROXY=http://sys-proxy-rd-relay.byted.org:8118; export NO_PROXY=byted.org,bytedance.net,10.*.*.*,127.*.*.*' alias proxy_off='unset http_proxy; unset https_proxy; unset no_proxy; unset HTTP_PROXY; unset HTTPS_PROXY; unset NO_PROXY' diff --git a/zshrc/prep_env.sh b/zshrc/prep_env.sh index 71533bf..fa11177 100644 --- a/zshrc/prep_env.sh +++ b/zshrc/prep_env.sh @@ -65,26 +65,6 @@ export PYSPARK_DRIVER_PYTHON="${PYSPARK_DRIVER_PYTHON:-/usr/bin/python3}" # 默认 local[2],和原 mlxrc 保持一致 export PYSPARK_SUBMIT_ARGS="${PYSPARK_SUBMIT_ARGS:---master local[2] pyspark-shell}" -# MLXLAB devbox code disk 标记(如果启动脚本已经设置,就不要覆盖) -if [[ -n "${MLXLAB_DEVBOX_CODE_DISK}" ]]; then -export MLXLAB_DEVBOX_CODE_DISK='' -fi - -# MLX / Merlin 相关变量(假设在容器启动时已经由 start_devbox.sh 导出) -# 这里统一再 export 一遍,保证交互 shell 也能继承 -export MLX_USER_TOKEN='bd2a3f1b71d54ab497f13f2eefc4f5bc' -export MLX_USER='qingyuhao' -export MLX_IMAGE_VID='d51qjdbc77u9kebl603g' -export MLX_IMAGE_URL='hub.byted.org/reckon/data.reckon.mlx.image_10786:4aa09c59c9cbb1fcde50526696177c84' -export MLX_ENGINE_SID='bgi0zldy6943b7db' -export MLX_DEVBOX_ID='132783' -export MLX_HOST_URL='https://ml.bytedance.net/' -export MERLIN_HOST_URL='https://ml.bytedance.net' -export TCC_CDN_HOST='//lf6-config.bytetcc.com/obj/tcc-config-web' -export ZTI_ENV='cn' -export IS_SEED='true' -export MLXLAB_DEVBOX_CODE_DISK='' - # DOAS_ZONE(从 BYTE_REGION 推导) if [[ "${BYTE_REGION}" == "CN" ]]; then export DOAS_ZONE="cn" @@ -154,7 +134,9 @@ if [[ "$WORKSPACE_ENVS_SET" != "1" ]]; then envfile="/etc/.container_env" if [[ -f $envfile ]]; then while IFS= read -r line; do + [[ "$line" == *=* ]] || continue _varname="${line%%=*}" + [[ "$_varname" =~ ^[a-zA-Z_][a-zA-Z0-9_]*$ ]] || continue if eval "[[ -z \"\${${_varname}+x}\" ]]"; then # env is not set export "${_varname}=${line#*=}" fi @@ -226,7 +208,9 @@ worker_envfile="/etc/worker_envs_$ARNOLD_WORKER_ID" user_worker_envfile="$HOME/.worker_envs/worker_envs_$ARNOLD_WORKER_ID" if [[ -f $user_worker_envfile ]]; then while IFS= read -r line; do + [[ "$line" == *=* ]] || continue _varname="${line%%=*}" + [[ "$_varname" =~ ^[a-zA-Z_][a-zA-Z0-9_]*$ ]] || continue if eval "[[ -z \"\${${_varname}+x}\" ]]"; then # env is not set export "${_varname}=${line#*=}" fi @@ -234,7 +218,9 @@ if [[ -f $user_worker_envfile ]]; then unset _varname elif [[ -f $worker_envfile ]]; then while IFS= read -r line; do + [[ "$line" == *=* ]] || continue _varname="${line%%=*}" + [[ "$_varname" =~ ^[a-zA-Z_][a-zA-Z0-9_]*$ ]] || continue if eval "[[ -z \"\${${_varname}+x}\" ]]"; then # env is not set export "${_varname}=${line#*=}" fi @@ -276,6 +262,7 @@ if [[ -f "$envfile" ]]; then # 跳过注释行和空行 [[ "$line" =~ ^[[:space:]]*# ]] && continue [[ "$line" =~ ^[[:space:]]*$ ]] && continue + [[ "$line" == *=* ]] || continue # 提取变量名和值 var_name="${line%%=*}" diff --git a/zshrc/pyenv.zsh b/zshrc/pyenv.zsh index 3acaabb..90f6842 100644 --- a/zshrc/pyenv.zsh +++ b/zshrc/pyenv.zsh @@ -1,4 +1,4 @@ # Initialize pyenv (Python Version Manager) export PYENV_ROOT="$HOME/.pyenv" [[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH" # Add pyenv to PATH -eval "$(pyenv init - zsh)" # This loads pyenv +command -v pyenv &> /dev/null && eval "$(pyenv init - zsh)"