| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428 |
- #!/bin/bash
- # =============================================================
- # tool-moyu.sh — AI「摸鱼」模拟器
- #
- # 作用:读取一段内容(默认本会话日志,或任意文件/stdin),
- # 循环「假装在处理」,模拟 AI 工作的样子。
- # 适合:需要看起来在干活、又不想真干活的时候 😏
- #
- # 用法:
- # ./tool-moyu.sh # 用内置内容摸鱼(默认)
- # ./tool-moyu.sh -n 3 # 循环 3 遍
- # ./tool-moyu.sh [文件] # 从文件读取(覆盖内置内容)
- # ./tool-moyu.sh --help # 帮助
- #
- # 选项:
- # -n N 循环 N 次(默认无限)
- # -d MS 每行间隔毫秒(默认随机 80-400)
- # -t 逐个字符「打字」效果
- # -s 静默模式:不打印假状态行,只循环内容
- # -c PCT 命中行的实际上色概率(0-100, 默认 35)
- # =============================================================
- set -euo pipefail
- LOOP_TIMES=0 # 0 = 无限
- DELAY_MS=0 # 0 = 随机 80-400
- TYPE_EFFECT=0
- SILENT=0
- COLOR_RATIO=35 # 0-100, 命中语义的行的实际上色概率(降彩色密度)
- show_usage() {
- sed -n '1,24p' "$0"
- exit 0
- }
- while [ $# -gt 0 ]; do
- case "$1" in
- -n)
- LOOP_TIMES="${2:?}"
- shift 2
- ;;
- -d)
- DELAY_MS="${2:?}"
- shift 2
- ;;
- -t)
- TYPE_EFFECT=1
- shift
- ;;
- -s)
- SILENT=1
- shift
- ;;
- -c | --color-ratio)
- COLOR_RATIO="${2:?}"
- case "$COLOR_RATIO" in *[!0-9]*)
- echo "Invalid color ratio: $COLOR_RATIO (expect 0-100)" >&2
- exit 1
- ;;
- esac
- [ "$COLOR_RATIO" -gt 100 ] && { echo "color ratio must be 0-100" >&2; exit 1; }
- shift 2
- ;;
- --help | -h) show_usage ;;
- -*)
- echo "Unknown option: $1" >&2
- exit 1
- ;;
- *) break ;;
- esac
- done
- # ---- 颜色自动检测:仅 TTY 或 FORCE_COLOR=1 才上色;NO_COLOR 显式禁用 ----
- # 文件模式不上色(见 run_once),此处仅决定随机内容是否套用 ANSI 主题色
- COLOR=0
- if [ -z "${NO_COLOR:-}" ] && { [ "${FORCE_COLOR:-0}" = "1" ] || [ -t 1 ]; }; then
- COLOR=1
- fi
- # ---- 命令与对应输出(成对,命令后紧跟其输出更真实) ----
- COMMANDS=(
- "go vet ./..."
- "go test ./..."
- "CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o admin_server ./cmd/server"
- "pnpm typecheck"
- "pnpm build"
- "rsync -az --delete release/frontend/ root@18.220.34.224:/www/wwwroot/household/"
- "ssh -p 10022 root@18.220.34.224 'systemctl restart backend-admin'"
- "mysql -h127.0.0.1 -uhousehold -p**** household -e 'SHOW TABLES;'"
- "curl -s -o /dev/null -w 'HTTP %{http_code}\\n' http://127.0.0.1:8081/"
- "journalctl -u backend-admin -n 30 --no-pager"
- "systemctl status backend-app"
- "git log --oneline -5"
- "go run ./cmd/migrate up"
- "pnpm lint"
- "pnpm test:unit"
- "docker compose ps"
- "redis-cli -h 127.0.0.1 INFO memory"
- "journalctl -u backend-app --since '10 min ago' --no-pager"
- "ssh -p 10022 root@18.220.34.224 'nginx -t'"
- "curl -s https://admin.household.ooo.ink/api/v1/health"
- "go test -race ./internal/pkg/notify/..."
- "git pull --rebase origin master"
- "git diff --stat"
- "docker exec household-mysql mysql -e 'SELECT COUNT(*) FROM center_orders'"
- "go build ./cmd/app"
- "go vet ./internal/pkg/..."
- "pnpm install --frozen-lockfile"
- "pnpm run typecheck:ci"
- "git status --short"
- "git stash && git pull && git stash pop"
- "mysql -h127.0.0.1 -uhousehold -p**** household -e 'OPTIMIZE TABLE center_orders'"
- "curl -s -o /dev/null -w '%{time_total}' http://127.0.0.1:8081/api/v1/orders/123"
- "go tool pprof -top /tmp/cpu.prof"
- "git tag v1.9.2 && git push origin v1.9.2"
- "redis-cli -n 3 dbsize"
- "journalctl -u backend-admin --since today --no-pager | grep -i error"
- )
- COMMAND_OUT=(
- "ok 0.231s"
- "ok git.ooo.ink/household/app 0.532s"
- "[build] release/backend/admin/admin_server (ELF, linux/amd64)"
- "no type errors found"
- "✓ built in 26.39s"
- "sent 2.4MB, 1.1MB/s"
- "systemd[1]: Started backend-admin.service - Household Backend Admin."
- "Tables: center_admins center_menus center_roles ... (19 total)"
- "HTTP 200"
- "[GIN-debug] Listening and serving HTTP on :8081"
- "Active: active (running)"
- "f37eec3 docs(deploy): align backend directory with actual test-machine paths"
- "migrate: applied 1 change (20260829003_create_notify_logs) in 312ms · dirty=0"
- "✔ No ESLint errors (148 files, 3.1s)"
- "Test Files: 6 passed | 48 tests (68.4s) ✓"
- "CONTAINER STATUS: mysql(Up) redis(Up) backend-app(Up 3 days) · 4/4 healthy"
- "used_memory_human:1.2G · peak 1.4G · maxmemory_policy:noeviction · keys 12840"
- "no new entries · last log 12 min ago, no warnings, no OOM"
- "nginx: configuration file /etc/nginx/nginx.conf test is successful"
- "{\"status\":\"ok\",\"version\":\"v1.9.2\",\"db\":\"up\",\"redis\":\"up\"}"
- "ok git.ooo.ink/household/app/internal/pkg/notify 3.812s · race detected 0"
- "Updating 8f3a2d1..c1e9b77 · 2 files changed, 41 insertions(+), 3 deletions(-)"
- "internal/router/route.go +3 · internal/pkg/notify/notify.go +96 · 2 files changed"
- "COUNT(*) = 128420 · +312 today, no archive lag"
- "ok git.ooo.ink/household/app 0.18s"
- "ok 0.421s"
- "pnpm: All dependencies are up to date (resolved in 6.2s)"
- "✓ 214 files checked, no type errors"
- " M internal/pkg/notify/notify.go · ?? docs/api/notify.md"
- "Auto-merging internal/pkg/notify/notify.go · stash applied, 1 conflict auto-resolved"
- "Table optimized · freed 118MB · fragmentation 0%"
- "0.184s"
- "concatstrings 12% · encoding/json.Encode 8% · runtime.mallocgc 6% · (42 nodes)"
- "* [new tag] v1.9.2 -> v1.9.2"
- "12840"
- "0 matches · clean today"
- )
- # ---- Standalone lines (tool returns / logs / a few AI actions) ----
- STANDALONE=(
- "[read] docs/deploy-aaPanel.md 168 lines (2.1 kB, 14 sections, 3 code blocks) · reviewed the Nginx config and systemd service sections, ready to follow the manual"
- "[read] internal/pkg/database/run_migrations.go 87 lines → located the RunMigrations entry · confirmed FIFO order + idempotent dedup, auto-rollback on failure"
- "[search] migrations → 3 results (run_migrations.go, migrate.go, main.go) · all are startup migration paths, no duplicate registration"
- "[search] CenterAdmin → 14 results · hit in admin routes/service/handler, test files excluded to avoid noise"
- "[trace] RunMigrations → cmd/server/main.go:41 ← internal/pkg/database.RunMigrations · called once from main only, no bypass path"
- "[trace] ParseToken → 6 callers: auth middleware ×1, ws handler ×2, cron ×3 · every call chain verified, no cyclic dependencies"
- "[snippet] buildDSN → user:pass@tcp(host:port)/db?parseTime=True&charset=utf8mb4 · reads DB_HOST/DB_PORT/DB_USER/DB_PASS from viper config"
- "[snippet] handleList → offset defaults to 0, limit caps at 100 with silent truncation · returns {total, items}, pagination contract for the frontend"
- "[grep] rabbitmq in docker-compose/dev.yml → 0 matches, dependency absent · queue-based notifications must degrade to synchronous calls"
- "[edit] internal/router/route.go +1 -2 → registered notify route under /api/v1 group · swagger annotations updated, takes effect after restart"
- "[write] internal/pkg/notify/notify.go 96 lines → new email/SMS notification wrapper with retry · 3s timeout, 2 retries, failures written to dead-letter table"
- "[deploy] backend-admin → active (running) · pid 1823 · 48MB RSS · managed by systemd, enabled on boot, listening on port 8081"
- "[deploy] frontend-admin → HTTP 200 · dist/assets/index-*.js uploaded · Nginx cache purged, all static assets now serve the new build"
- "[check] SSH root@18.220.34.224:10022 → ok (handshake 0.42s, key auth passed) · passwordless channel healthy, follow-up commands can run directly"
- "[verify] curl admin.household.ooo.ink → 200 OK (TTFB 86ms, no 5xx) · homepage returns full HTML, every static asset is 200"
- "[verify] mysql SHOW TABLES → 19 tables · 312MB total · covers center/tenant/order core groups, no orphaned tables"
- "[verify] redis ping → PONG · 1.2GB/4GB in use · 92% hit ratio, all keys carry business prefix, no collisions"
- "[skip] migration 20260829002 already applied · dirty=0, nothing to re-run · this release ships no new migration scripts"
- "[skip] no changes, up to date · working tree clean, nothing pending · fully in sync with origin/master, no push required"
- "[warn] config.yaml placeholder secret left as-is · must be replaced in production · prefer env-var injection over hardcoding"
- "[warn] TLS cert expires in 12 days, renew soon · Let's Encrypt auto-renew cron confirmed running"
- "[warn] pkg/notify has 3 leftover TODOs: email templates not i18n'ed · JA/CN templates to be added next iteration"
- "[err] rate limit exceeded, auto-retry in 1.8s... · 2nd retry succeeded, request replayed"
- "ready for connections. socket: '/var/run/mysqld/mysqld.sock' port: 3306 · MySQL 8.4 up, version compatibility check passed"
- "schema_migrations: 20260828001 | dirty=0 · last migration 2026-08-28 10:02:34 · 47 entries in history, no conflicts"
- "dist/assets/index-*.js 95.77 kB │ gzip: 37.38 kB │ 8 chunks · 12.4% smaller than previous build, tree-shaking effective"
- "vite v7.3.6 building client environment for production... 26.39s ✓ · output 4.2MB, zero warnings, dist.zip produced"
- "GET /api/v1/orders 200 4.2ms · source: center db, Redis cache hit · no DB touch, no new entries in slow-query log"
- "POST /api/v1/orders 201 12.8ms · triggered worker assignment + notification push · status transition normal, transaction committed"
- "center_admins: 6 rows returned in 1ms (SELECT id, name, role_ids FROM center_admins) · PRIMARY index used, no full scan"
- "db 15/16 used, 1 left · one idle pool reserved · leak detection clean, avg idle 3.2s"
- "service worker: 34 active jobs today, avg response 2.1s · spread across Tokyo/Osaka/Fukuoka, no timeouts"
- "🤖 analyzing dependency graph... 1284 symbols, 8 clusters, 2 cyclic deps · flagged for decoupling, no impact on this change"
- "📊 summarizing key decisions... 4 items: routing/caching/payments/compliance · synced to project ADR for later review"
- "✍️ drafting implementation plan... 5 steps, ~40 min · migration/route/service/test/docs, each with acceptance criteria"
- "✅ implementation plan approved · no blockers · passed 2 reviewers, all risks low/medium, execution started"
- "📐 aligning with existing architecture (ARCHITECTURE.md §3 layering) · new module follows cmd→internal→shared one-way dependency"
- "🏗️ scaffolding new module: internal/pkg/notify (service/repository/template) · directory layout matches the skeleton conventions"
- "🧩 wiring DI container... injected logger + db + redis deps · constructor signatures updated, compiles clean"
- "🧪 writing unit tests for RunMigrations · 3 cases: success/duplicate/failed-rollback · covers edges, 87% coverage"
- "⚙️ running gofmt -l + go vet ./... → 0 format issues, 0 vet warnings · no unrelated files reformatted"
- "📦 bumping go.mod dependency: gin v1.10.0 → v1.11.0 (CVE-2026-0113 fix) · go.sum synced, compile regression-free"
- "📝 updating API docs (docs/api/notify.md) · added 2 endpoint specs · req/resp examples + error codes, linked from README"
- "🧠 loading knowledge graph index (codebase-memory)... 12s · covers 3 sub-repos, last indexed 5 min ago"
- "🔎 querying codebase graph for CenterAdmin handlers → 6 nodes expanded · located create/update/delete/query ops"
- "🚦 checking index coverage: project/backend/admin → 100% covered, no gaps · unindexed historical branches excluded"
- "👣 tracing callers of ParseToken → all 6 refs verified · each carries auth context, no privilege-escalation calls"
- "🧬 detecting git diff impact (blast radius) → touches router + 2 handlers · 4 related tests run and green"
- "🗃️ index refreshed: 1284 symbols, 8 clusters, 312 files, 0 stale · +23 symbols, −5, topology acyclic"
- "[test] TestParseToken → PASS (0.112s, 4/4 asserts) · covers expired/tampered/malformed/valid tokens"
- "[test] TestBuildDSN → PASS (0.031s, 5/5 asserts, empty-password edge) · includes fallback when host:port has no default"
- "[bench] BenchmarkList → 1.2µs/op, 812 allocs/op, 0 B/op leaked · 18% faster than baseline, acceptable"
- "[lint] staticcheck ./... → no issues reported · last run 10 min ago · full golangci-lint suite also green"
- "[git] status → clean (working tree) · no untracked files · 3 commits staged, awaiting push"
- "[git] log --oneline -3 → 3 commits behind origin, need pull · upstream added config refactor + dependency bumps"
- "Redis: 127.0.0.1:6379 connected · maxclients 10000 · 15/16 dbs used · AOF persistence on, no blocking commands"
- "[build] docker build -t registry.git.ooo.ink/household/backend:1.9.2 . → 2 layers cached, image 187MB pushed in 4.8s"
- "[build] pnpm build:admin → 4.2MB dist, tree-shook lodash-es, gzip 1.1MB · zero warnings"
- "[lint] gofmt -l → 0 files · consistent with .editorconfig"
- "[test] go test ./... → ok (7 packages) · 2.8s, 0 skipped, no race"
- "[bench] BenchmarkHandleList → 420ns/op, 3 allocs/op · inlined hot path, 30% faster"
- "[migrate] 20260829002_orders_partition OK · down migration present, reversible"
- "[db] ANALYZE TABLE center_orders → 128k rows · cardinality updated, planner now uses orders_idx_created"
- "[redis] SCAN 'order:*' → 12 keys · all with TTL < 24h, none expired-but-resident"
- "[nginx] reloaded (graceful) · worker_connections 1024, 3 upstreams healthy"
- "[backup] daily dump → /backup/household_$(date +%F).sql.gz 48MB · checksum verified, offsite copy synced"
- "[cron] certbot renew --dry-run → certificate not yet due (17 days left)"
- "[git] push origin master → 4 commits up, hooks ran, CI passed"
- "[git] rebase complete · replayed 6 commits onto origin/master, no conflicts"
- "[docs] CHANGELOG.md +1.9.2 → 3 features, 5 fixes, 2 security patches"
- "[arch] layering still one-way (cmd→internal→shared) · no new import cycles, graph check green"
- "[perf] slow-query log (1h) → 0 entries above 100ms · indexes effective under new partition layout"
- "[warn] disk usage /var 78% · logrotate daily, expect stable below 85%"
- "[err] worker#2 panic recovered · 1 job lost, requeued to DLQ for manual review"
- "[ci] pipeline #417 → all 12 jobs passed · 4m12s, zero flakes this week"
- "[review] PR #318 → 2 approvals · comments resolved, codeowner sign-off in"
- "[lint] govulncheck ./... → 0 known vulnerabilities · scan 20s"
- "[test] coverage diff +3.2% on notify pkg · overall 87.4% maintained"
- "[race] go test -race ./... → ok · 0 races across 6 packages"
- "[db] EXPLAIN SELECT ... WHERE created_at > now() → uses orders_idx_created · no temp table"
- "[redis] INFO stats → hits 92.4% misses 7.6% · evictions 0 in last 24h"
- "[metrics] Prometheus scrape → 214 series healthy · 3 targets up, 0 down"
- "[backup] restore dry-run on staging → 47/47 tables verified, checksum match"
- "[i18n] en/ja/zh-cn locales in sync · 98 strings, 0 missing keys"
- "[migrate] down migration ran on staging → reversible, schema back to prior state"
- "[cron] daily order reconciliation → 0 mismatches · settled + unpaid tallied"
- "[cache] warmup on deploy → 8.2k keys preloaded in 2.1s · cold-hit avoided"
- "[security] zap scan → 0 high, 3 medium (info-leak headers) · tracked in backlog"
- "[sso] token refresh job → ok · 214 sessions rotated, none expired mid-flight"
- "[observability] trace sample rate 5% · p95 spans < 800ms across service mesh"
- )
- # 输出/日志/错误行(可重复,作为“裸输出”随机插入)
- OUTPUTS=(
- "PASS"
- "ok"
- "HTTP 200"
- "Active: active (running)"
- "[GIN-debug] Listening and serving HTTP on :8081"
- "warn: chunk size exceeds 4000 kB"
- 'ERROR: failed to open source "file://internal/migrations"'
- "FATAL: database connection refused, retrying..."
- "0 error(s), 5 warning(s)"
- "migrations completed successfully"
- "no type errors found"
- "✓ 307 modules transformed."
- "Build succeeded after 3 retries"
- "done"
- "Compiled successfully."
- "exit code 0"
- "✓ 4 checks passed."
- "200 OK"
- "Deploy complete."
- "WARN: 3 unused route handlers detected"
- "WARN: log file rotated, reopening"
- "ERROR: context deadline exceeded (Client.Timeout)"
- "panic: runtime error: index out of range"
- "gofmt: no files need formatting"
- "lint clean · 0 warnings"
- "Test run finished: 3 passed, 0 failed"
- "security scan: 0 critical, 2 medium findings"
- "cache flushed"
- "up to date"
- "done · 0 errors"
- "Build successful"
- "ok (10 tests)"
- "WARN: slow query detected (1.2s > 100ms threshold)"
- "ERROR: cannot allocate memory in thread cache"
- "fatal: unable to access remote: Could not resolve host"
- "test: all passed"
- "checks passed: 6/6"
- "Deploy aborted: health check failed"
- "200 OK (cached)"
- "gzip: 1.9MB → 610KB saved"
- "→ build #417 succeeded in 24.8s"
- )
- # 动态随机数字行(消除固定值反复出现)
- gen_rand_lines() {
- local n=$((1 + RANDOM % 4)) # 1-4 条
- local i r
- for ((i = 0; i < n; i++)); do
- r=$((RANDOM % 7))
- case $r in
- 0) echo "ok $(awk -v seed=$RANDOM 'BEGIN{srand(seed); printf "%.3f", 0.05+rand()*1.5}')s" ;;
- 1) echo "dist/assets/index-*.js $(awk -v seed=$RANDOM 'BEGIN{srand(seed); printf "%.2f", 8+rand()*300}') kB │ gzip: $(awk -v seed=$RANDOM 'BEGIN{srand(seed); printf "%.2f", 3+rand()*80}') kB" ;;
- 2) echo "Progress: $((5 + RANDOM % 95))%..." ;;
- 3) echo "$((1 + RANDOM % 40)) test(s), $((RANDOM % 4)) failed" ;;
- 4) echo "deploy $(awk -v seed=$RANDOM 'BEGIN{srand(seed); for(i=0;i<6;i++) printf "%c", 97+int(rand()*26)}') · $(awk -v seed=$RANDOM 'BEGIN{srand(seed); printf "%.1f", 0.1+rand()*3}')s · service healthy" ;;
- 5) echo "p99 latency: $(awk -v seed=$RANDOM 'BEGIN{srand(seed); printf "%.1f", 5+rand()*180}') ms · $(awk -v seed=$RANDOM 'BEGIN{srand(seed); printf "%.1f", 1+rand()*9}')k req/min" ;;
- 6) echo "mem: $(awk -v seed=$RANDOM 'BEGIN{srand(seed); printf "%d", 120+rand()*400}') MB RSS · $(awk -v seed=$RANDOM 'BEGIN{srand(seed); printf "%d", 3+rand()*12}')% over baseline" ;;
- esac
- done
- }
- # 返回 $1 个不重复随机下标(0..$2-1)
- pick_unique() {
- local count=$1 pool=$2
- [ "$pool" -lt "$count" ] && count=$pool
- seq 0 $((pool - 1)) | sort -R | head -n "$count"
- }
- # 随机生成一段“工作日志”:命令(约一半带输出)+独立行+裸输出+动态数字,洗牌打乱
- # 块大小不规则、数字随机化,消除固定模式与重复数字
- gen_random_content() {
- local cmdc=$((1 + RANDOM % 5)) # 1-5 条命令
- local stc=$((2 + RANDOM % 6)) # 2-7 条独立行
- local ci si oi i
- LINES=()
- # 命令:约一半紧跟输出(不一定成对,制造不规则块)
- for ci in $(pick_unique "$cmdc" "${#COMMANDS[@]}"); do
- LINES+=("\$ ${COMMANDS[$ci]}")
- if [ $((RANDOM % 2)) -eq 0 ]; then LINES+=("${COMMAND_OUT[$ci]}"); fi
- [ $((RANDOM % 4)) -eq 0 ] && LINES+=("") # 随机空行
- done
- # 独立行(不重复)
- for si in $(pick_unique "$stc" "${#STANDALONE[@]}"); do
- LINES+=("${STANDALONE[$si]}")
- [ $((RANDOM % 3)) -eq 0 ] && LINES+=("") # 随机空行
- done
- # 裸输出行(可重复)
- for ((i = 0; i < $((2 + RANDOM % 4)); i++)); do
- LINES+=("${OUTPUTS[$((RANDOM % ${#OUTPUTS[@]}))]}")
- done
- # 动态随机数字行
- while IFS= read -r l; do LINES+=("$l"); done < <(gen_rand_lines)
- # 洗牌打乱整体顺序
- local idx=($(seq 0 $((${#LINES[@]} - 1)) | sort -R))
- local shuffled=()
- for i in "${idx[@]}"; do shuffled+=("${LINES[$i]}"); done
- LINES=("${shuffled[@]}")
- }
- # 内容来源:文件参数 > 随机生成
- CONTENT="${1-}"
- FILE_MODE=0
- if [ -n "$CONTENT" ] && [ -f "$CONTENT" ]; then
- mapfile -t LINES <"$CONTENT"
- FILE_MODE=1
- elif [ -n "$CONTENT" ] && [ "$CONTENT" != "-" ]; then
- echo "File not found: $CONTENT, falling back to random content." >&2
- gen_random_content
- else
- gen_random_content
- fi
- [ "${#LINES[@]}" -eq 0 ] && {
- echo "Content empty, nothing to slack on." >&2
- exit 1
- }
- # 随机延时
- rand_delay() {
- if [ "$DELAY_MS" -gt 0 ]; then
- sleep "$(awk -v d="$DELAY_MS" 'BEGIN{printf "%.3f", d/1000}')"
- else sleep "$(awk -v lo=80 -v hi=400 -v seed=$RANDOM 'BEGIN{srand(seed); printf "%.3f", (lo+int(rand()*(hi-lo+1)))/1000}')"; fi
- }
- # 按内容语义配色(优先级:命令 > 致命 > 错误 > 警告 > 成功 > 默认)
- # 命令=青 / FATAL=红加粗 / 错误=红 / 警告=黄 / 成功=绿;仅随机生成模式调用
- colorize() {
- local line="$1" code=""
- case "$line" in
- '$ '*) code='\033[1;36m' ;;
- *[Ff][Aa][Tt][Aa][Ll]*) code='\033[1;31m' ;;
- *ERROR* | *ERR:* | *\[err\]* | *err:*) code='\033[31m' ;;
- *warn* | *WARN*) code='\033[33m' ;;
- *'✓'* | *PASS* | *'ok '* | *'HTTP 200'* | *PONG* | *'no type errors'* | *'completed successfully'* | *'Build succeeded'*) code='\033[32m' ;;
- esac
- if [ -n "$code" ]; then
- # 概率门控: 仅约 COLOR_RATIO% 的命中行真正上彩(降彩色密度); 100=全彩 0=全无色
- if [ "$COLOR_RATIO" -ge 100 ] || [ $((RANDOM % 100)) -lt "$COLOR_RATIO" ]; then
- printf '%s%s\033[0m' "$code" "$line"
- else
- printf '%s' "$line"
- fi
- else
- printf '%s' "$line"
- fi
- }
- run_once() {
- local line
- for line in "${LINES[@]}"; do
- local out="$line"
- # 文件模式或终端不支持颜色 → 原样输出
- if [ "$FILE_MODE" = "0" ] && [ "$COLOR" = "1" ]; then out=$(colorize "$line"); fi
- if [ "$TYPE_EFFECT" = "1" ]; then
- local i
- for ((i = 0; i < ${#out}; i++)); do
- printf "%s" "${out:i:1}"
- rand_delay
- done
- echo ""
- else
- printf '%s\n' "$out"
- fi
- rand_delay
- done
- echo "" # 每遍之间空行
- }
- n=0
- while [ "$LOOP_TIMES" -eq 0 ] || [ "$n" -lt "$LOOP_TIMES" ]; do
- n=$((n + 1))
- # 每轮重新生成随机内容(避免内容固定导致反复重复);文件模式则用固定内容
- [ "$FILE_MODE" = "0" ] && gen_random_content
- run_once
- done
- exit 0
|