penguin/utils

my env utils

commit 56ae4b4ed96709c0a02f76eb9b21d4a7338eef06

author斟酌 鵬兄 <tgckpg@gmail.com>
date2026-06-26T11:10:08Z
subjectFixed rbash-upgrade failing
commit 56ae4b4ed96709c0a02f76eb9b21d4a7338eef06
Author: 斟酌 鵬兄 <tgckpg@gmail.com>
Date:   2026-06-26T11:10:08Z

    Fixed rbash-upgrade failing
---
 bash/core/50_upgrade.bash | 86 +++++++++++++++++++++++++++++++++++-----------
 bash/rbashrc              | 87 ++++++++++++++++++++++++++++++++++++-----------
 bash/rbashrc.in           |  2 +-
 3 files changed, 136 insertions(+), 39 deletions(-)

diff --git a/bash/core/50_upgrade.bash b/bash/core/50_upgrade.bash
index c81bb34..c7aed09 100755
--- a/bash/core/50_upgrade.bash
+++ b/bash/core/50_upgrade.bash
@@ -1,35 +1,83 @@
 rbash-upgrade() {
-  echo "Updating $__RBASH_SCRIPT"
+  local target url tmp rendered backup
+  local host domain color content
 
-  local tmp new_host new_domain new_color
-  tmp="$(mktemp)"
+  target="$__RBASH_SCRIPT"
+  url="$(rbash_url "rbashrc")"
 
-  rbash_download "$(rbash_url "rbashrc")" > "$tmp" || {
+  host="${1:-$RHOSTNAME}"
+  domain="${2:-$RDOMAIN}"
+  color="${3:-$RCOLOR}"
+
+  echo "Updating $target"
+
+  tmp="$(mktemp "${TMPDIR:-/tmp}/rbashrc.download.XXXXXX")" || return 1
+  rendered="$(mktemp "${TMPDIR:-/tmp}/rbashrc.rendered.XXXXXX")" || {
     rm -f "$tmp"
     return 1
   }
 
-  if [ -n "${1:-}" ]; then
-    new_host="$1"
-    new_domain="${2:-}"
-    new_color="${3:-$RCOLOR}"
-  else
-    new_host="$RHOSTNAME"
-    new_domain="$RDOMAIN"
-    new_color="$RCOLOR"
+  if ! rbash_download "$url" > "$tmp"; then
+    echo "rbash: upgrade download failed: $url" >&2
+    rm -f "$tmp" "$rendered"
+    return 1
+  fi
+
+  if [ ! -s "$tmp" ]; then
+    echo "rbash: downloaded rbashrc is empty; refusing to install" >&2
+    rm -f "$tmp" "$rendered"
+    return 1
   fi
 
-  sed \
-    -e "s|<HOSTNAME>|$new_host|g" \
-    -e "s|<DOMAIN>|$new_domain|g" \
-    -e "s|<RCOLOR>|$new_color|g" \
-    "$tmp" > "$tmp.new"
+  content="$(cat "$tmp")"
+
+  content="${content//<HOSTNAME>/$host}"
+  content="${content//<DOMAIN>/$domain}"
+  content="${content//<RCOLOR>/$color}"
+
+  printf '%s\n' "$content" > "$rendered" || {
+    echo "rbash: failed to render new rbashrc" >&2
+    rm -f "$tmp" "$rendered"
+    return 1
+  }
+
+  if ! grep -q 'RBASH_HOME' "$rendered"; then
+    echo "rbash: rendered file does not look like rbashrc; refusing to install" >&2
+    rm -f "$tmp" "$rendered"
+    return 1
+  fi
+
+  if ! bash -n "$rendered"; then
+    echo "rbash: rendered rbashrc has syntax errors; refusing to install" >&2
+    rm -f "$tmp" "$rendered"
+    return 1
+  fi
+
+  backup="$target.bak.$(date +%Y%m%d%H%M%S)"
+
+  if [ -f "$target" ]; then
+    cp "$target" "$backup" || {
+      echo "rbash: failed to create backup: $backup" >&2
+      rm -f "$tmp" "$rendered"
+      return 1
+    }
+    echo "Backup: $backup"
+  fi
+
+  chmod 700 "$rendered"
+
+  if ! mv "$rendered" "$target"; then
+    echo "rbash: failed to replace $target" >&2
+    echo "rbash: backup remains at $backup" >&2
+    rm -f "$tmp" "$rendered"
+    return 1
+  fi
 
-  mv "$tmp.new" "$__RBASH_SCRIPT"
   rm -f "$tmp"
 
   rm -rf "$RBASH_CACHE_DIR"
+  mkdir -p "$RBASH_CACHE_DIR"
 
   # shellcheck source=/dev/null
-  source "$__RBASH_SCRIPT"
+  source "$target"
 }
\ No newline at end of file
diff --git a/bash/rbashrc b/bash/rbashrc
index caf5516..a0caa2d 100755
--- a/bash/rbashrc
+++ b/bash/rbashrc
@@ -26,6 +26,7 @@ RHOSTNAME="<HOSTNAME>"
 RDOMAIN="<DOMAIN>"
 RCOLOR="<RCOLOR>"
 
+
 # ---- rbash: bash/core/00_env.bash ----
 
 # Host prompt placeholders can be replaced by rbash-upgrade/install.
@@ -376,39 +377,87 @@ r2dissource() {
 # ---- rbash: bash/core/50_upgrade.bash ----
 
 rbash-upgrade() {
-  echo "Updating $__RBASH_SCRIPT"
+  local target url tmp rendered backup
+  local host domain color content
 
-  local tmp new_host new_domain new_color
-  tmp="$(mktemp)"
+  target="$__RBASH_SCRIPT"
+  url="$(rbash_url "rbashrc")"
+
+  host="${1:-$RHOSTNAME}"
+  domain="${2:-$RDOMAIN}"
+  color="${3:-$RCOLOR}"
+
+  echo "Updating $target"
 
-  rbash_download "$(rbash_url "rbashrc")" > "$tmp" || {
+  tmp="$(mktemp "${TMPDIR:-/tmp}/rbashrc.download.XXXXXX")" || return 1
+  rendered="$(mktemp "${TMPDIR:-/tmp}/rbashrc.rendered.XXXXXX")" || {
     rm -f "$tmp"
     return 1
   }
 
-  if [ -n "${1:-}" ]; then
-    new_host="$1"
-    new_domain="${2:-}"
-    new_color="${3:-$RCOLOR}"
-  else
-    new_host="$RHOSTNAME"
-    new_domain="$RDOMAIN"
-    new_color="$RCOLOR"
+  if ! rbash_download "$url" > "$tmp"; then
+    echo "rbash: upgrade download failed: $url" >&2
+    rm -f "$tmp" "$rendered"
+    return 1
   fi
 
-  sed \
-    -e "s|<HOSTNAME>|$new_host|g" \
-    -e "s|<DOMAIN>|$new_domain|g" \
-    -e "s|<RCOLOR>|$new_color|g" \
-    "$tmp" > "$tmp.new"
+  if [ ! -s "$tmp" ]; then
+    echo "rbash: downloaded rbashrc is empty; refusing to install" >&2
+    rm -f "$tmp" "$rendered"
+    return 1
+  fi
+
+  content="$(cat "$tmp")"
+
+  content="${content//<HOSTNAME>/$host}"
+  content="${content//<DOMAIN>/$domain}"
+  content="${content//<RCOLOR>/$color}"
+
+  printf '%s\n' "$content" > "$rendered" || {
+    echo "rbash: failed to render new rbashrc" >&2
+    rm -f "$tmp" "$rendered"
+    return 1
+  }
+
+  if ! grep -q 'RBASH_HOME' "$rendered"; then
+    echo "rbash: rendered file does not look like rbashrc; refusing to install" >&2
+    rm -f "$tmp" "$rendered"
+    return 1
+  fi
+
+  if ! bash -n "$rendered"; then
+    echo "rbash: rendered rbashrc has syntax errors; refusing to install" >&2
+    rm -f "$tmp" "$rendered"
+    return 1
+  fi
+
+  backup="$target.bak.$(date +%Y%m%d%H%M%S)"
+
+  if [ -f "$target" ]; then
+    cp "$target" "$backup" || {
+      echo "rbash: failed to create backup: $backup" >&2
+      rm -f "$tmp" "$rendered"
+      return 1
+    }
+    echo "Backup: $backup"
+  fi
+
+  chmod 700 "$rendered"
+
+  if ! mv "$rendered" "$target"; then
+    echo "rbash: failed to replace $target" >&2
+    echo "rbash: backup remains at $backup" >&2
+    rm -f "$tmp" "$rendered"
+    return 1
+  fi
 
-  mv "$tmp.new" "$__RBASH_SCRIPT"
   rm -f "$tmp"
 
   rm -rf "$RBASH_CACHE_DIR"
+  mkdir -p "$RBASH_CACHE_DIR"
 
   # shellcheck source=/dev/null
-  source "$__RBASH_SCRIPT"
+  source "$target"
 }
 
 # ---- rbash: bash/core/90_prompt.bash ----
diff --git a/bash/rbashrc.in b/bash/rbashrc.in
index 694703a..26f87b9 100644
--- a/bash/rbashrc.in
+++ b/bash/rbashrc.in
@@ -24,4 +24,4 @@ RBASH_BIN="$RBASH_HOME/bin"
 
 RHOSTNAME="<HOSTNAME>"
 RDOMAIN="<DOMAIN>"
-RCOLOR="<RCOLOR>"
\ No newline at end of file
+RCOLOR="<RCOLOR>"