Skip to content

Commit 2100ceb

Browse files
committed
docs: 添加多语言 OpenClaw 卸载指南及清理脚本
新增中文和英文双语教程,详细说明在 Windows、Linux 和 macOS 系统上彻底卸载 OpenClaw 的步骤。同时提供针对各平台的自动化清理脚本(PowerShell/Bash),用于检测并移除 Node.js 全局包及 Docker 容器/镜像残留。
1 parent 0bde138 commit 2100ceb

8 files changed

Lines changed: 1299 additions & 0 deletions

File tree

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
#!/usr/bin/env bash
2+
#
3+
# OpenClaw Cleanup Script (Linux version)
4+
# Function: Detect and uninstall openclaw packages on Linux
5+
#
6+
# Execution flow:
7+
# 1. Check if Node.js exists → exit if not found
8+
# 2. Check package manager (npm/pnpm)
9+
# 3. Check if openclaw packages exist → exit if not found
10+
# 4. Stop all node processes → exit with error if failed
11+
# 5. Uninstall openclaw packages → exit with success
12+
#
13+
14+
# Silent mode flag
15+
SILENT=false
16+
if [[ "$1" == "-s" ]] || [[ "$1" == "--silent" ]]; then
17+
SILENT=true
18+
fi
19+
20+
# Set UTF-8 encoding
21+
export LANG=en_US.UTF-8
22+
export LC_ALL=en_US.UTF-8
23+
24+
# ============================================
25+
# Logging Setup (Must be defined first)
26+
# ============================================
27+
LOG_DIR="/tmp/openclaw-cleanup"
28+
29+
mkdir -p "$LOG_DIR" 2>/dev/null
30+
LOG_FILE="$LOG_DIR/Cleanup_$(date +'%Y%m%d_%H%M%S').log"
31+
32+
write_log() {
33+
local message="$1"
34+
local level="${2:-Info}"
35+
local timestamp=$(date +'%Y-%m-%d %H:%M:%S')
36+
local log_line="[$timestamp] [$level] $message"
37+
echo "$log_line" >> "$LOG_FILE"
38+
if [ "$SILENT" = false ]; then
39+
case "$level" in
40+
"Success") echo -e "\e[32m[SUCCESS] $message\e[0m" ;;
41+
"Error") echo -e "\e[31m[ERROR] $message\e[0m" ;;
42+
"Info") echo -e "\e[36m[INFO] $message\e[0m" ;;
43+
*) echo "[$level] $message" ;;
44+
esac
45+
fi
46+
}
47+
48+
write_log "========== OpenClaw Cleanup Script (Linux) Started ==========" "Info"
49+
50+
# ============================================
51+
# Environment Setup: Ensure Node.js is in PATH
52+
# ============================================
53+
export PATH="/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:$PATH"
54+
55+
write_log "Searching for Node.js in user directories..." "Info"
56+
for user_home in /home/*; do
57+
if [ -d "$user_home/.nvm" ]; then
58+
export NVM_DIR="$user_home/.nvm"
59+
if [ -s "$NVM_DIR/nvm.sh" ]; then
60+
\. "$NVM_DIR/nvm.sh"
61+
write_log "Sourced NVM for user $(basename "$user_home")" "Success"
62+
fi
63+
fi
64+
done
65+
66+
if [ -d "$HOME/.nvm" ]; then
67+
export NVM_DIR="$HOME/.nvm"
68+
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
69+
fi
70+
71+
72+
# ============================================
73+
# Step 1-5: Local Node.js Package Cleanup
74+
# ============================================
75+
cleanup_local_node_packages() {
76+
write_log "Starting local Node.js package cleanup..." "Info"
77+
78+
# --- Check for Node.js ---
79+
if ! command -v node &> /dev/null; then
80+
write_log "Node.js not found, skipping local package cleanup." "Info"
81+
return # Exit function, not script
82+
fi
83+
write_log "Node.js detected, version: $(node --version)" "Success"
84+
85+
# --- Check for package manager ---
86+
package_manager=""
87+
if command -v pnpm &> /dev/null; then package_manager="pnpm";
88+
elif command -v npm &> /dev/null; then package_manager="npm"; fi
89+
90+
if [ -z "$package_manager" ]; then
91+
write_log "Neither npm nor pnpm found, skipping local package cleanup." "Info"
92+
return # Exit function, not script
93+
fi
94+
write_log "Using package manager: $package_manager" "Success"
95+
96+
# --- Check for openclaw packages ---
97+
target_packages=("openclaw" "openclaw-cn")
98+
found_packages=()
99+
for pkg in "${target_packages[@]}"; do
100+
if [ "$package_manager" = "npm" ] && npm list -g "$pkg" --depth=0 2>&1 | grep -qE "$pkg@[0-9]"; then
101+
found_packages+=("$pkg")
102+
elif [ "$package_manager" = "pnpm" ] && ! pnpm list -g "$pkg" --depth=0 2>&1 | grep -q "No packages found"; then
103+
found_packages+=("$pkg")
104+
fi
105+
done
106+
107+
if [ ${#found_packages[@]} -eq 0 ]; then
108+
write_log "No openclaw packages detected locally." "Info"
109+
return # Exit function, not script
110+
fi
111+
write_log "Found packages to uninstall: ${found_packages[*]}" "Info"
112+
113+
# --- Stop node processes ---
114+
write_log "Stopping node processes..." "Info"
115+
local node_pids=$(pgrep -x node)
116+
if [ -n "$node_pids" ]; then
117+
for pid in $node_pids; do kill -TERM "$pid" 2>/dev/null; done
118+
sleep 2
119+
for pid in $(pgrep -x node); do kill -9 "$pid" 2>/dev/null; done
120+
fi
121+
122+
# --- Uninstall packages ---
123+
SUDO=""
124+
if [ "$EUID" -ne 0 ] && [ ! -w "$(npm root -g 2>/dev/null)" ]; then SUDO="sudo"; fi
125+
for pkg in "${found_packages[@]}"; do
126+
write_log "Uninstalling $pkg..." "Info"
127+
if $SUDO "$package_manager" uninstall -g "$pkg" &>/dev/null; then
128+
write_log "Successfully uninstalled: $pkg" "Success"
129+
else
130+
write_log "Failed to uninstall: $pkg" "Error"
131+
fi
132+
done
133+
}
134+
135+
136+
# ============================================
137+
# Docker Cleanup Function (Multi-User & Rootless Aware)
138+
# ============================================
139+
cleanup_docker() {
140+
write_log "Starting comprehensive Docker cleanup..." "Info"
141+
142+
if ! command -v docker &> /dev/null; then
143+
write_log "Docker command not found, skipping." "Info"
144+
return
145+
fi
146+
147+
# 1. Collect all potential Docker Sockets (System-wide + Rootless)
148+
local sockets=()
149+
[ -S "/var/run/docker.sock" ] && sockets+=("/var/run/docker.sock")
150+
151+
# Search for rootless docker sockets
152+
for user_sock in /run/user/*/docker.sock; do
153+
[ -S "$user_sock" ] && sockets+=("$user_sock")
154+
done
155+
156+
if [ ${#sockets[@]} -eq 0 ]; then
157+
write_log "No active Docker sockets found." "Info"
158+
return
159+
fi
160+
161+
for sock in "${sockets[@]}"; do
162+
write_log "Cleaning Docker instance at $sock..." "Info"
163+
export DOCKER_HOST="unix://$sock"
164+
165+
# Find and remove containers
166+
local containers=$(docker ps -a -q --filter "name=openclaw" 2>/dev/null)
167+
if [ -n "$containers" ]; then
168+
docker stop $containers &>/dev/null
169+
docker rm $containers &>/dev/null
170+
write_log "Removed containers at $sock" "Success"
171+
fi
172+
173+
# Find and remove images
174+
local images=$(docker images -q "*openclaw*" 2>/dev/null)
175+
if [ -n "$images" ]; then
176+
docker rmi -f $images &>/dev/null
177+
write_log "Removed images at $sock" "Success"
178+
fi
179+
180+
unset DOCKER_HOST
181+
done
182+
}
183+
184+
185+
# ============================================
186+
# Main Execution
187+
# ============================================
188+
cleanup_local_node_packages
189+
cleanup_docker
190+
191+
write_log "========== Cleanup Completed ==========" "Success"
192+
exit 0
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
#!/usr/bin/env bash
2+
#
3+
# OpenClaw Cleanup Script v6
4+
# Function: Detect and uninstall openclaw packages on employee computers
5+
#
6+
# Execution flow:
7+
# 1. Check if Node.js exists → exit if not found
8+
# 2. Check package manager (npm/pnpm)
9+
# 3. Check if openclaw packages exist → exit if not found
10+
# 4. Stop all node processes → exit with error if failed
11+
# 5. Uninstall openclaw packages → exit with success
12+
#
13+
14+
# Silent mode flag
15+
SILENT=false
16+
if [[ "$1" == "-s" ]] || [[ "$1" == "--silent" ]]; then
17+
SILENT=true
18+
fi
19+
20+
# Set UTF-8 encoding
21+
export LANG=en_US.UTF-8
22+
export LC_ALL=en_US.UTF-8
23+
24+
# ============================================
25+
# Environment Setup: Ensure Node.js is in PATH
26+
# ============================================
27+
# 1. Add common macOS installation paths
28+
export PATH="/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/homebrew/bin:$PATH"
29+
30+
# 2. If node is still not found, try to locate it from the console user's environment
31+
if ! command -v node &> /dev/null; then
32+
CONSOLE_USER=$(stat -f%Su /dev/console)
33+
if [ -n "$CONSOLE_USER" ] && [ "$CONSOLE_USER" != "root" ]; then
34+
# Try to get node path from user's login shell
35+
USER_NODE=$(sudo -u "$CONSOLE_USER" -i which node 2>/dev/null)
36+
if [ -n "$USER_NODE" ]; then
37+
USER_NODE_DIR=$(dirname "$USER_NODE")
38+
export PATH="$USER_NODE_DIR:$PATH"
39+
fi
40+
fi
41+
fi
42+
43+
# Log directory - prefer ~/Library/Logs
44+
LOG_DIR="$HOME/Library/Logs/openclaw-cleanup"
45+
if ! mkdir -p "$LOG_DIR" 2>/dev/null; then
46+
# Fallback to temp directory
47+
LOG_DIR=$(mktemp -d)
48+
fi
49+
LOG_FILE="$LOG_DIR/Cleanup_$(date +'%Y%m%d_%H%M%S').log"
50+
51+
# Output function
52+
write_log() {
53+
local message="$1"
54+
local level="${2:-Info}"
55+
local timestamp=$(date +'%Y-%m-%d %H:%M:%S')
56+
local log_line="[$timestamp] [$level] $message"
57+
58+
# write to log file
59+
echo "$log_line" >> "$LOG_FILE"
60+
61+
# Console output (only when not silent)
62+
if [ "$SILENT" = false ]; then
63+
case "$level" in
64+
"Success") echo "[SUCCESS] $message" ;;
65+
"Error") echo "[ERROR] $message" ;;
66+
"Info") echo "[INFO] $message" ;;
67+
*) echo "[$level] $message" ;;
68+
esac
69+
fi
70+
}
71+
72+
write_log "========== OpenClaw Cleanup Script Started ==========" "Info"
73+
74+
# ============================================
75+
# Local Node.js Package Cleanup Function
76+
# ============================================
77+
cleanup_local_node_packages() {
78+
write_log "Starting local Node.js package cleanup..." "Info"
79+
80+
if ! command -v node &> /dev/null; then
81+
write_log "Node.js not found, skipping local package cleanup." "Info"
82+
return
83+
fi
84+
85+
local package_manager=""
86+
if command -v pnpm &> /dev/null; then package_manager="pnpm"
87+
elif command -v npm &> /dev/null; then package_manager="npm"
88+
fi
89+
90+
if [ -z "$package_manager" ]; then
91+
write_log "No package manager found, skipping local package cleanup." "Info"
92+
return
93+
fi
94+
95+
local target_packages=("openclaw" "openclaw-cn")
96+
local found_packages=()
97+
for pkg in "${target_packages[@]}"; do
98+
if $package_manager list -g "$pkg" --depth=0 2>&1 | grep -qE "$pkg@[0-9]"; then
99+
found_packages+=("$pkg")
100+
fi
101+
done
102+
103+
if [ ${#found_packages[@]} -eq 0 ]; then
104+
write_log "No openclaw packages detected locally." "Info"
105+
return
106+
fi
107+
108+
write_log "Stopping node processes..." "Info"
109+
local node_pids=$(pgrep -x node)
110+
if [ -n "$node_pids" ]; then
111+
for pid in $node_pids; do kill -TERM "$pid" 2>/dev/null; done
112+
sleep 2
113+
for pid in $(pgrep -x node); do kill -9 "$pid" 2>/dev/null; done
114+
fi
115+
116+
for pkg in "${found_packages[@]}"; do
117+
write_log "Uninstalling $pkg..." "Info"
118+
if $package_manager uninstall -g "$pkg" &>/dev/null; then
119+
write_log "Successfully uninstalled $pkg" "Success"
120+
else
121+
write_log "Failed to uninstall $pkg" "Error"
122+
fi
123+
done
124+
}
125+
126+
127+
# ============================================
128+
# Step 6: Docker Cleanup for openclaw
129+
# ============================================
130+
cleanup_docker() {
131+
write_log "Checking for Dockerized openclaw..." "Info"
132+
133+
if ! command -v docker &> /dev/null; then
134+
write_log "Docker not found, skipping Docker cleanup." "Info"
135+
return
136+
fi
137+
138+
write_log "Docker found. Searching for openclaw containers and images..." "Success"
139+
140+
# On macOS, Docker Desktop usually runs without sudo
141+
# Find and stop/remove containers
142+
containers=$(docker ps -a -q --filter "name=openclaw")
143+
if [ -n "$containers" ]; then
144+
write_log "Found openclaw containers. Stopping and removing them..." "Info"
145+
docker stop $containers &>/dev/null
146+
docker rm $containers &>/dev/null
147+
write_log "Stopped and removed openclaw containers." "Success"
148+
else
149+
write_log "No openclaw containers found." "Info"
150+
fi
151+
152+
# Find and remove images
153+
images=$(docker images -q "*openclaw*")
154+
if [ -n "$images" ]; then
155+
write_log "Found openclaw images. Removing them..." "Info"
156+
docker rmi -f $images &>/dev/null
157+
write_log "Removed openclaw images." "Success"
158+
else
159+
write_log "No openclaw images found." "Info"
160+
fi
161+
}
162+
163+
# ============================================
164+
# Main Execution
165+
# ============================================
166+
167+
# Run local package cleanup first
168+
cleanup_local_node_packages
169+
170+
# Always run Docker cleanup
171+
cleanup_docker
172+
173+
write_log "========== Cleanup Completed ==========" "Success"
174+
exit 0

0 commit comments

Comments
 (0)