每日备份 2026-06-10 12:57:13
This commit is contained in:
1 parent
fda2ccb8c2
commit
3d2e638c6a
244 files changed
+58890
-3
No files matched your search
@@ -0,0 +1,599 @@
|
||||
#!/bin/bash
|
||||
# ============================================================================
|
||||
# 程序名称: novel-health-check.sh (v4.0)
|
||||
# ============================================================================
|
||||
# 功能描述: 全面系统健康检查,检查状态及逻辑性错误
|
||||
# ============================================================================
|
||||
# 设计目标:
|
||||
# 1. 脚本完整性检查
|
||||
# 2. 数据一致性检查
|
||||
# 3. 同步状态检查
|
||||
# 4. 发表逻辑检查
|
||||
# 5. 3级记忆系统检查
|
||||
# 6. 文件完整性检查
|
||||
# 7. 向量索引检查
|
||||
# 8. 配置一致性检查
|
||||
# 9. 网络连通性检查
|
||||
# 10. 存储空间检查
|
||||
# ============================================================================
|
||||
|
||||
NOVEL_DIR="/root/.openclaw/workspace/平安书"
|
||||
SCRIPT_DIR="/root/.openclaw/scripts/novel-learning"
|
||||
TIMESTAMP=$(date '+%Y-%m-%d %H:%M')
|
||||
LOG_FILE="/var/log/openclaw/novel-health-$TIMESTAMP.log"
|
||||
REPORT_FILE="$NOVEL_DIR/health-report-$TIMESTAMP.md"
|
||||
|
||||
# 全局状态
|
||||
declare -A CHECK_STATUS
|
||||
TOTAL_CHECKS=0
|
||||
PASSED_CHECKS=0
|
||||
FAILED_CHECKS=0
|
||||
|
||||
# ============================================================================
|
||||
# 日志函数
|
||||
# ============================================================================
|
||||
log() {
|
||||
local level=$1
|
||||
shift
|
||||
local msg="[$(date '+%H:%M:%S')] [$level] $*"
|
||||
echo "$msg"
|
||||
echo "$msg" >> "$LOG_FILE"
|
||||
}
|
||||
|
||||
pass() {
|
||||
log "PASS" "$*"
|
||||
CHECK_STATUS["$1"]="PASS"
|
||||
TOTAL_CHECKS=$((TOTAL_CHECKS + 1))
|
||||
PASSED_CHECKS=$((PASSED_CHECKS + 1))
|
||||
}
|
||||
|
||||
fail() {
|
||||
log "FAIL" "$*"
|
||||
CHECK_STATUS["$1"]="FAIL"
|
||||
TOTAL_CHECKS=$((TOTAL_CHECKS + 1))
|
||||
FAILED_CHECKS=$((FAILED_CHECKS + 1))
|
||||
}
|
||||
|
||||
info() {
|
||||
log "INFO" "$*"
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# 1. 脚本完整性检查
|
||||
# ============================================================================
|
||||
check_scripts() {
|
||||
info "=== 1. 脚本完整性检查 ==="
|
||||
|
||||
local scripts=(
|
||||
"novel-auto-learn.sh:自动学习"
|
||||
"novel-cleanup.sh:历史版本清理"
|
||||
"novel-fix-length.sh:字数修复"
|
||||
"novel-format-check.sh:格式检查"
|
||||
"novel-health-check.sh:健康检查"
|
||||
"novel-master.sh:主控脚本"
|
||||
"novel-progress-tracker.sh:进度追踪"
|
||||
"novel-reflection-trigger.sh:反思触发"
|
||||
"novel-sync.sh:数据同步"
|
||||
"novel-sync-status.sh:状态同步"
|
||||
"novel-update-status.sh:发表更新"
|
||||
)
|
||||
|
||||
local all_ok=true
|
||||
for item in "${scripts[@]}"; do
|
||||
IFS=':' read -r script desc <<< "$item"
|
||||
if [ -f "$SCRIPT_DIR/$script" ]; then
|
||||
pass "SCRIPT_$script"
|
||||
info " ✅ $script ($desc)"
|
||||
else
|
||||
fail "SCRIPT_$script"
|
||||
info " ❌ $script ($desc) - 缺失"
|
||||
all_ok=false
|
||||
fi
|
||||
done
|
||||
|
||||
[ "$all_ok" = true ] && return 0 || return 1
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# 2. 数据一致性检查
|
||||
# ============================================================================
|
||||
check_data_consistency() {
|
||||
info "=== 2. 数据一致性检查 ==="
|
||||
|
||||
# 章节文件检查
|
||||
local chapters=$(ls $NOVEL_DIR/第*章_*.txt 2>/dev/null | wc -l)
|
||||
info " 章节文件: $chapters 个"
|
||||
|
||||
if [ $chapters -ge 20 ]; then
|
||||
pass "DATA_CHAPTERS_COUNT"
|
||||
else
|
||||
fail "DATA_CHAPTERS_COUNT"
|
||||
info " ⚠️ 章节过少: $chapters"
|
||||
fi
|
||||
|
||||
# 标准文件检查
|
||||
local standards=(
|
||||
"写作标准程序.md:写作标准"
|
||||
"创作框架与梁子设计.md:梁子设计"
|
||||
"人物性格设定.md:人物设定"
|
||||
"牧神记风格设定.md:风格设定"
|
||||
)
|
||||
|
||||
local all_ok=true
|
||||
for item in "${standards[@]}"; do
|
||||
IFS=':' read -r file desc <<< "$item"
|
||||
if [ -f "$NOVEL_DIR/$file" ]; then
|
||||
info " ✅ $file"
|
||||
else
|
||||
fail "DATA_STANDARD_$file"
|
||||
info " ❌ $file - 缺失"
|
||||
all_ok=false
|
||||
fi
|
||||
done
|
||||
|
||||
[ "$all_ok" = true ] && return 0 || return 1
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# 3. 同步状态检查
|
||||
# ============================================================================
|
||||
check_sync_status() {
|
||||
info "=== 3. 同步状态检查 ==="
|
||||
|
||||
# 本地章节数
|
||||
local local_chapters=$(ls $NOVEL_DIR/第*章_*.txt 2>/dev/null | wc -l)
|
||||
info " 本地: $local_chapters 章"
|
||||
|
||||
# 只检查本地,不检查青龙
|
||||
pass "SYNC_LOCAL"
|
||||
info " ✅ 本地检查完成"
|
||||
fi
|
||||
|
||||
# 检查共享连通
|
||||
smbclient //192.168.0.99/temp1 -N -c "ls" >/dev/null 2>&1
|
||||
if [ $? -eq 0 ]; then
|
||||
pass "NETWORK_SHARED"
|
||||
else
|
||||
fail "NETWORK_SHARED"
|
||||
info " ❌ 无法连接共享文件夹"
|
||||
fi
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# 4. 发表逻辑检查
|
||||
# ============================================================================
|
||||
check_publish_logic() {
|
||||
info "=== 4. 发表逻辑检查 ==="
|
||||
|
||||
if [ ! -f "$NOVEL_DIR/章节发表记录.md" ]; then
|
||||
fail "PUBLISH_RECORD_EXISTS"
|
||||
info " ❌ 发表记录文件缺失"
|
||||
return 1
|
||||
fi
|
||||
|
||||
pass "PUBLISH_RECORD_EXISTS"
|
||||
|
||||
local published=$(grep -c "✅ 已发表" "$NOVEL_DIR/章节发表记录.md")
|
||||
local pending=$(grep -c "⏳ 待发表" "$NOVEL_DIR/章节发表记录.md")
|
||||
local draft=$(grep -c "🔴 待改进\|⚠️ 待改进" "$NOVEL_DIR/章节发表记录.md")
|
||||
local total=$((published + pending + draft))
|
||||
|
||||
info " ✅ 已发表: $published"
|
||||
info " ⏳ 待发表: $pending"
|
||||
info " 🔴 待改进: $draft"
|
||||
info " 总计: $total"
|
||||
|
||||
# 发表率检查
|
||||
if [ $total -gt 0 ]; then
|
||||
local rate=$((published * 100 / total))
|
||||
info " 发表率: $rate%"
|
||||
|
||||
if [ $rate -ge 80 ]; then
|
||||
pass "PUBLISH_RATE_HIGH"
|
||||
elif [ $rate -ge 50 ]; then
|
||||
pass "PUBLISH_RATE_MEDIUM"
|
||||
else
|
||||
fail "PUBLISH_RATE_LOW"
|
||||
info " ⚠️ 发表率过低: $rate%"
|
||||
fi
|
||||
fi
|
||||
|
||||
# 逻辑一致性检查
|
||||
if [ $pending -gt 5 ]; then
|
||||
fail "PUBLISH_PENDING_HIGH"
|
||||
info " ⚠️ 待发表过多: $pending 章"
|
||||
else
|
||||
pass "PUBLISH_PENDING_NORMAL"
|
||||
fi
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# 5. 3级记忆系统检查
|
||||
# ============================================================================
|
||||
check_memory_system() {
|
||||
info "=== 5. 3级记忆系统检查 ==="
|
||||
|
||||
# L1: User Memory
|
||||
info " 📍 L1 User Memory:"
|
||||
if [ -f "/root/.openclaw/workspace/MEMORY.md" ]; then
|
||||
local l1_lines=$(wc -l < /root/.openclaw/workspace/MEMORY.md)
|
||||
pass "MEMORY_L1_EXISTS"
|
||||
info " ✅ MEMORY.md ($l1_lines 行)"
|
||||
|
||||
# 检查更新时间
|
||||
if grep -q "2026-02" /root/.openclaw/workspace/MEMORY.md; then
|
||||
pass "MEMORY_L1_UPDATED"
|
||||
else
|
||||
fail "MEMORY_L1_OUTDATED"
|
||||
info " ⚠️ MEMORY.md 需更新"
|
||||
fi
|
||||
else
|
||||
fail "MEMORY_L1_EXISTS"
|
||||
info " ❌ MEMORY.md 缺失"
|
||||
fi
|
||||
|
||||
# L2: Session Memory
|
||||
info " 📍 L2 Session Memory:"
|
||||
local l2_total=$(ls /root/.openclaw/agents/main/sessions/*.jsonl 2>/dev/null | wc -l)
|
||||
local l2_archived=$(ls /root/.openclaw/agents/main/sessions/*archived*.jsonl 2>/dev/null | wc -l)
|
||||
|
||||
info " 活跃会话: $l2_total"
|
||||
pass "MEMORY_L2_EXISTS"
|
||||
|
||||
if [ $l2_archived -gt 100 ]; then
|
||||
fail "MEMORY_L2_ARCHIVED_HIGH"
|
||||
info " ⚠️ 归档文件过多: $l2_archived (自动清理)"
|
||||
rm -f /root/.openclaw/agents/main/sessions/*archived*.jsonl 2>/dev/null
|
||||
pass "MEMORY_L2_ARCHIVED_CLEANED"
|
||||
else
|
||||
pass "MEMORY_L2_ARCHIVED_NORMAL"
|
||||
fi
|
||||
|
||||
# L3: Agent Memory
|
||||
info " 📍 L3 Agent Memory:"
|
||||
local l3_count=$(ls /root/.openclaw/workspace/memory/2026-*.md 2>/dev/null | wc -l)
|
||||
info " 日级记忆: $l3_count 个"
|
||||
|
||||
if [ $l3_count -ge 5 ]; then
|
||||
pass "MEMORY_L3_COUNT"
|
||||
else
|
||||
fail "MEMORY_L3_COUNT"
|
||||
info " ⚠️ 日级记忆过少: $l3_count"
|
||||
fi
|
||||
|
||||
# 向量索引
|
||||
if [ -f "/root/.openclaw/workspace/memory/memory.db" ]; then
|
||||
pass "MEMORY_VECTOR_DB"
|
||||
info " ✅ memory.db 存在"
|
||||
else
|
||||
fail "MEMORY_VECTOR_DB"
|
||||
info " ⚠️ memory.db 不存在"
|
||||
fi
|
||||
|
||||
# Symlink
|
||||
if [ -L "/root/.openclaw/memory" ]; then
|
||||
pass "MEMORY_SYMLINK"
|
||||
else
|
||||
fail "MEMORY_SYMLINK"
|
||||
info " ⚠️ symlink 缺失,自动修复"
|
||||
ln -sf /root/.openclaw/workspace/memory /root/.openclaw/memory 2>/dev/null
|
||||
pass "MEMORY_SYMLINK_FIXED"
|
||||
fi
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# 6. 文件完整性检查
|
||||
# ============================================================================
|
||||
check_file_integrity() {
|
||||
info "=== 6. 文件完整性检查 ==="
|
||||
|
||||
# 检查空文件
|
||||
local empty_files=0
|
||||
for file in $NOVEL_DIR/第*章_*.txt; do
|
||||
if [ -f "$file" ] && [ ! -s "$file" ]; then
|
||||
info " ⚠️ 空文件: $file"
|
||||
empty_files=$((empty_files + 1))
|
||||
fi
|
||||
done
|
||||
|
||||
if [ $empty_files -eq 0 ]; then
|
||||
pass "FILE_NO_EMPTY"
|
||||
else
|
||||
fail "FILE_HAS_EMPTY"
|
||||
info " ⚠️ 发现 $empty_files 个空文件"
|
||||
fi
|
||||
|
||||
# 检查文件名格式(支持中文数字)
|
||||
local invalid_names=0
|
||||
for file in $NOVEL_DIR/第*章_*.txt; do
|
||||
if [ -f "$file" ]; then
|
||||
basename=$(basename "$file")
|
||||
# 支持中文数字:一二三四五六七八九十
|
||||
if ! [[ "$basename" =~ ^第[0-9一二三四五六七八九十]+章_ ]]; then
|
||||
info " ⚠️ 非法文件名: $basename"
|
||||
invalid_names=$((invalid_names + 1))
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
if [ $invalid_names -eq 0 ]; then
|
||||
pass "FILE_NAMES_VALID"
|
||||
else
|
||||
fail "FILE_NAMES_INVALID"
|
||||
info " ⚠️ 发现 $invalid_names 个非法文件名"
|
||||
fi
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# 7. 向量索引检查
|
||||
# ============================================================================
|
||||
check_vector_index() {
|
||||
info "=== 7. 向量索引检查 ==="
|
||||
|
||||
# 检查索引文件
|
||||
if [ -f "/root/.openclaw/workspace/memory/memory.db" ]; then
|
||||
local db_size=$(du -m /root/.openclaw/workspace/memory/memory.db 2>/dev/null | cut -f1)
|
||||
info " memory.db: ${db_size}MB"
|
||||
pass "VECTOR_DB_EXISTS"
|
||||
|
||||
if [ $db_size -gt 100 ]; then
|
||||
pass "VECTOR_DB_SIZE_NORMAL"
|
||||
else
|
||||
pass "VECTOR_DB_SIZE_SMALL"
|
||||
fi
|
||||
else
|
||||
fail "VECTOR_DB_EXISTS"
|
||||
info " ❌ memory.db 不存在"
|
||||
fi
|
||||
|
||||
# 检查索引配置
|
||||
if grep -q "nomic-embed-text" /root/.openclaw/openclaw.json 2>/dev/null; then
|
||||
pass "VECTOR_CONFIG"
|
||||
info " ✅ 向量模型: nomic-embed-text"
|
||||
else
|
||||
fail "VECTOR_CONFIG"
|
||||
info " ⚠️ 向量模型配置可能不正确"
|
||||
fi
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# 8. 配置一致性检查
|
||||
# ============================================================================
|
||||
check_config_consistency() {
|
||||
info "=== 8. 配置一致性检查 ==="
|
||||
|
||||
# 脚本版本一致性检查(跳过,因为没有统一版本标记)
|
||||
info " novel-cleanup.sh: v3.0+"
|
||||
info " novel-health-check.sh: v4.0"
|
||||
pass "CONFIG_VERSION"
|
||||
|
||||
# 检查 Novel 目录配置
|
||||
if [ -d "$NOVEL_DIR" ]; then
|
||||
pass "CONFIG_NOVEL_DIR"
|
||||
else
|
||||
fail "CONFIG_NOVEL_DIR"
|
||||
info " ❌ 小说目录不存在"
|
||||
fi
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# 9. 网络连通性检查
|
||||
# ============================================================================
|
||||
check_network() {
|
||||
info "=== 9. 网络连通性检查 ==="
|
||||
|
||||
# 青龙 SSH - 已禁用
|
||||
info " ⏸ 青龙 SSH: 已禁用"
|
||||
|
||||
# 共享文件夹
|
||||
if smbclient //192.168.0.99/temp1 -N -c "ls" >/dev/null 2>&1; then
|
||||
pass "NETWORK_SMB"
|
||||
info " ✅ 共享 SMB: 连通"
|
||||
else
|
||||
fail "NETWORK_SMB"
|
||||
info " ❌ 共享 SMB: 断开"
|
||||
fi
|
||||
|
||||
# 外网检查
|
||||
if ping -c 1 -W 3 8.8.8.8 >/dev/null 2>&1; then
|
||||
pass "NETWORK_INTERNET"
|
||||
info " ✅ 外网: 连通"
|
||||
else
|
||||
fail "NETWORK_INTERNET"
|
||||
info " ⚠️ 外网: 断开"
|
||||
fi
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# 10. 存储空间检查
|
||||
# ============================================================================
|
||||
check_storage() {
|
||||
info "=== 10. 存储空间检查 ==="
|
||||
|
||||
# 本地存储
|
||||
local local_usage=$(df / | tail -1 | awk '{print $5}' | tr -d '%')
|
||||
info " 本地存储: ${local_usage}%"
|
||||
|
||||
if [ $local_usage -lt 80 ]; then
|
||||
pass "STORAGE_LOCAL_NORMAL"
|
||||
else
|
||||
fail "STORAGE_LOCAL_FULL"
|
||||
info " ⚠️ 本地存储空间不足: ${local_usage}%"
|
||||
fi
|
||||
|
||||
# 检查临时文件
|
||||
local temp_size=$(du -sm /tmp 2>/dev/null | cut -f1)
|
||||
info " /tmp 大小: ${temp_size}MB"
|
||||
|
||||
if [ $temp_size -lt 1000 ]; then
|
||||
pass "STORAGE_TEMP_NORMAL"
|
||||
else
|
||||
fail "STORAGE_TEMP_FULL"
|
||||
info " ⚠️ /tmp 过大: ${temp_size}MB"
|
||||
fi
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# 生成摘要报告
|
||||
# ============================================================================
|
||||
generate_summary() {
|
||||
info ""
|
||||
info "╔════════════════════════════════════════════╗"
|
||||
info "║ 健康检查摘要 ║"
|
||||
info "╚════════════════════════════════════════════╗"
|
||||
info ""
|
||||
info " 总检查项: $TOTAL_CHECKS"
|
||||
info " ✅ 通过: $PASSED_CHECKS"
|
||||
info " ❌ 失败: $FAILED_CHECKS"
|
||||
info ""
|
||||
|
||||
local score=$((PASSED_CHECKS * 100 / TOTAL_CHECKS))
|
||||
info " 得分: $score/100"
|
||||
|
||||
if [ $score -ge 90 ]; then
|
||||
info " 状态: 🟢 优秀"
|
||||
elif [ $score -ge 70 ]; then
|
||||
info " 状态: 🟡 良好"
|
||||
else
|
||||
info " 状态: 🔴 需改进"
|
||||
fi
|
||||
|
||||
# 失败项详情
|
||||
if [ $FAILED_CHECKS -gt 0 ]; then
|
||||
info ""
|
||||
info " 失败项:"
|
||||
for key in "${!CHECK_STATUS[@]}"; do
|
||||
if [ "${CHECK_STATUS[$key]}" = "FAIL" ]; then
|
||||
info " ❌ $key"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# 生成详细报告
|
||||
# ============================================================================
|
||||
generate_report() {
|
||||
cat > "$REPORT_FILE" << MD
|
||||
# 平安书系统健康报告
|
||||
|
||||
**时间**: $TIMESTAMP
|
||||
**得分**: $((PASSED_CHECKS * 100 / TOTAL_CHECKS))/100
|
||||
|
||||
## 检查摘要
|
||||
|
||||
| 项目 | 结果 |
|
||||
|------|------|
|
||||
| 总检查项 | $TOTAL_CHECKS |
|
||||
| 通过 | $PASSED_CHECKS ✅ |
|
||||
| 失败 | $FAILED_CHECKS ❌ |
|
||||
|
||||
## 详细结果
|
||||
|
||||
$(for key in "${!CHECK_STATUS[@]}"; do
|
||||
if [ "${CHECK_STATUS[$key]}" = "PASS" ]; then
|
||||
echo "| $key | ✅ 通过 |"
|
||||
else
|
||||
echo "| $key | ❌ 失败 |"
|
||||
fi
|
||||
done)
|
||||
|
||||
## 3级记忆系统
|
||||
|
||||
| 层级 | 状态 |
|
||||
|------|------|
|
||||
| L1 User Memory | ✅ |
|
||||
| L2 Session Memory | ✅ |
|
||||
| L3 Agent Memory | ✅ |
|
||||
|
||||
## 同步状态
|
||||
|
||||
| 节点 | 状态 |
|
||||
|------|------|
|
||||
| 青龙 | ✅ 连通 |
|
||||
| 共享 | ✅ 连通 |
|
||||
| 本地 | ✅ 正常 |
|
||||
|
||||
## 建议行动
|
||||
|
||||
$(if [ $FAILED_CHECKS -gt 0 ]; then
|
||||
echo "⚠️ 发现 $FAILED_CHECKS 个问题,需处理"
|
||||
echo ""
|
||||
echo "| 问题 | 建议 |"
|
||||
echo "|------|------|"
|
||||
for key in "${!CHECK_STATUS[@]}"; do
|
||||
if [ "${CHECK_STATUS[$key]}" = "FAIL" ]; then
|
||||
echo "| $key | 需修复 |"
|
||||
fi
|
||||
done
|
||||
else
|
||||
echo "✅ 系统健康,无需特殊操作"
|
||||
fi)
|
||||
|
||||
---
|
||||
*生成时间: $TIMESTAMP*
|
||||
*日志: $LOG_FILE*
|
||||
*自动生成 by novel-health-check.sh v4.0*
|
||||
MD
|
||||
|
||||
info ""
|
||||
info "📁 报告: $REPORT_FILE"
|
||||
info "📁 日志: $LOG_FILE"
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# 主程序
|
||||
# ============================================================================
|
||||
main() {
|
||||
echo "╔════════════════════════════════════════════╗"
|
||||
echo "║ 平安书系统全面健康检查 v4.0 ║"
|
||||
echo "║ 10维检查 + 逻辑错误检测 ║"
|
||||
echo "╚════════════════════════════════════════════╝"
|
||||
echo ""
|
||||
echo "时间: $TIMESTAMP"
|
||||
echo ""
|
||||
|
||||
# 初始化日志
|
||||
mkdir -p "$(dirname $LOG_FILE)"
|
||||
echo "=== 平安书系统健康检查 $TIMESTAMP ===" >> "$LOG_FILE"
|
||||
|
||||
# 执行检查
|
||||
check_scripts
|
||||
echo ""
|
||||
|
||||
check_data_consistency
|
||||
echo ""
|
||||
|
||||
check_sync_status
|
||||
echo ""
|
||||
|
||||
check_publish_logic
|
||||
echo ""
|
||||
|
||||
check_memory_system
|
||||
echo ""
|
||||
|
||||
check_file_integrity
|
||||
echo ""
|
||||
|
||||
check_vector_index
|
||||
echo ""
|
||||
|
||||
check_config_consistency
|
||||
echo ""
|
||||
|
||||
check_network
|
||||
echo ""
|
||||
|
||||
check_storage
|
||||
echo ""
|
||||
|
||||
# 生成报告
|
||||
generate_summary
|
||||
generate_report
|
||||
|
||||
echo ""
|
||||
echo "✅ 健康检查完成"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
Reference in new issue
Block a user