🔧 v1.0.9 — Shell polish and log formatting improvements

- Fixed “sh: bad number” errors in status output
- Compact single-line stats in view-logs
- Improved numeric parsing and input sanitization
- Unified timestamp format and safer defaults
This commit is contained in:
rE-Bo0t.bx1
2025-11-07 02:31:47 +08:00
parent 5b1a2ee069
commit 97737d5ba8
4 changed files with 93 additions and 34 deletions

View File

@@ -17,7 +17,54 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
---
## [1.0.8] - 2025-11-08
## [1.0.9] - 2025-11-07
🧠 **Maintenance and polish release** improving shell reliability, output consistency, and readability across status and log utilities.
🎨 Streamlined log viewer formatting, sanitized numeric parsing, and removed noisy shell error messages for cleaner execution.
### ✨ Added
* 🧩 Input sanitization helpers to ensure safe numeric evaluation in all status checks
* 🧱 Integrated integer guard function (`is_integer`) to prevent bad-number shell errors
* 🕒 Unified UTC timestamp formatting for consistent output across commands
### 🧰 Improvements
* 📜 `view-logs`: Compact single-line statistics (`📊 Stats: total | errors | warnings`) for cleaner display
* 🧅 `status`: Sanitized bootstrap parsing and error-free numeric comparison
* ⚙️ Hardened `set -e` handling with fallback defaults for missing values
* 🧩 Refined whitespace and CRLF handling in log parsing for improved compatibility
* 🧰 General shell cleanup and quoting improvements for portability across BusyBox, Alpine, and Debian-based images
### 🐛 Fixed
* 🧹 Removed recurring `sh: 0: bad number` warnings in `status` output
* 🧩 Fixed multi-line log stats formatting issue in `view-logs`
* 🔧 Corrected potential false negatives in `BOOTSTRAP_PERCENT` extraction
* 🧠 Resolved misinterpretation of empty variables during numeric comparisons
### 🔒 Security
* 🧩 Verified `set -e` safety to prevent unintended script exits on minor grep/curl failures
* 🛡️ Strengthened input filtering to prevent malformed log content injection into shell context
---
### 🧠 Developer Notes
* ✅ Both `status` and `view-logs` scripts tested under Alpine BusyBox and Debian Dash shells
* 🧩 Scripts now fully pass shellcheck (`shfmt` + POSIX mode) validation
* 💡 Compatible with Docker health checks and CI/CD validation hooks
---
**🧱 Summary:**
> *Tor Guard Relay v1.0.9 delivers a clean, error-free shell experience, better numeric safety, and a polished command-line output for monitoring and log viewing.*
---
## [1.0.8] - 2025-11-07
🧠 **Polish and refinement release** focused on versioning automation, tag safety, and improved metadata accuracy.
⚙️ Streamlined validation logic, consistent changelog generation, and safer build workflows.
@@ -135,15 +182,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
| Version | Status | Support Level |
| --------- | --------------------- | ------------------------------------------- |
| **1.0.8** | 🟢 🛡️ **Active** | Full support (current stable) |
| **1.0.7** | 🟡 🔧 **Maintenance** | Security + critical fixes only |
| **1.0.6** | 🟠 ⚠️ **Legacy** | Security patches only upgrade recommended |
| **1.0.5** | 🔴 ❌ **EOL** | No support upgrade immediately |
| **1.0.9** | 🟢 🛡️ **Active** | Full support (current stable) |
| **1.0.8** | 🟡 🔧 **Maintenance** | Security + critical fixes only |
| **1.0.7** | 🟠 ⚠️ **Legacy** | Security patches only upgrade recommended |
| **1.0.6** | 🔴 ❌ **EOL** | No support upgrade immediately |
---
## 🔗 Release Links
[1.0.9]: https://github.com/r3bo0tbx1/tor-guard-relay/releases/tag/v1.0.9
[1.0.8]: https://github.com/r3bo0tbx1/tor-guard-relay/releases/tag/v1.0.8
[1.0.7]: https://github.com/r3bo0tbx1/tor-guard-relay/releases/tag/v1.0.7
[1.0.6]: https://github.com/r3bo0tbx1/tor-guard-relay/releases/tag/v1.0.6
@@ -152,7 +200,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
[1.0.3]: https://github.com/r3bo0tbx1/tor-guard-relay/releases/tag/v1.0.3
[1.0.2]: https://github.com/r3bo0tbx1/tor-guard-relay/releases/tag/v1.0.2
[1.0.1]: https://github.com/r3bo0tbx1/tor-guard-relay/releases/tag/v1.0.1
[1.0.0]: https://github.com/r3bo0tbx1/tor-guard-relay/releases/tag/v1.0
[Unreleased]: https://github.com/r3bo0tbx1/tor-guard-relay/compare/v1.0.8...HEAD
---

View File

@@ -163,7 +163,7 @@ See [Deployment Guide](docs/DEPLOYMENT.md) for complete instructions.
## 🔧 Diagnostic Tools
**v1.0.8 includes 9 production-ready diagnostic tools** - no external scripts needed!
**v1.0.9 includes 9 production-ready diagnostic tools** - no external scripts needed!
### Quick Reference
@@ -190,7 +190,7 @@ docker exec tor-relay status
🧅 Tor Relay Status Report
═══════════════════════════════════
📦 Build: v1.0.8 (2025-11-06, amd64)
📦 Build: v1.0.9 (2025-11-06, amd64)
🚀 Bootstrap: ✅ 100% Complete
🔗 ORPort: ✅ Reachable (9001)
📊 Uptime: 2d 14h 30m
@@ -278,7 +278,7 @@ docker-compose -f docker-compose-multi-relay.yml up -d
## 📚 Documentation
**v1.0.8 includes comprehensive documentation** organized by topic:
**v1.0.9 includes comprehensive documentation** organized by topic:
### Getting Started
- **[Deployment Guide](docs/DEPLOYMENT.md)** - Complete installation for Docker CLI, Compose, Cosmos Cloud, and Portainer
@@ -554,7 +554,7 @@ Images are automatically rebuilt weekly to include security patches:
![GitHub Stars](https://img.shields.io/github/stars/r3bo0tbx1/tor-guard-relay?style=for-the-badge)
![GitHub Issues](https://img.shields.io/github/issues/r3bo0tbx1/tor-guard-relay?style=for-the-badge)
**Current Version:** v1.0.8
**Current Version:** v1.0.9
**Status:** Production Ready
**Last Build:** Weekly (Mondays 03:00 JST)
**Registries:** Docker Hub • GHCR

View File

@@ -5,7 +5,7 @@
set -e
# Configuration
VERSION="1.0.4"
VERSION="1.0.9"
OUTPUT_FORMAT="${OUTPUT_FORMAT:-text}"
SHOW_ALL="${SHOW_ALL:-true}"
CHECK_NETWORK="${CHECK_NETWORK:-true}"
@@ -29,6 +29,14 @@ format_ip_status() {
fi
}
# Safe integer check
is_integer() {
case "$1" in
''|*[!0-9]*) return 1 ;;
*) return 0 ;;
esac
}
# Parse arguments
for arg in "$@"; do
case "$arg" in
@@ -74,41 +82,43 @@ done
# Gather all status information
gather_status() {
IS_RUNNING="false"
if pgrep -x tor > /dev/null 2>&1; then
if pgrep -x tor >/dev/null 2>&1; then
IS_RUNNING="true"
PID=$(pgrep -x tor | head -1)
UPTIME=$(ps -o etime= -p "$PID" 2>/dev/null | tr -d ' ' || echo "0")
fi
BOOTSTRAP_PERCENT=0
BOOTSTRAP_MESSAGE=""
if [ -f /var/log/tor/notices.log ]; then
BOOTSTRAP_LINE=$(grep "Bootstrapped" /var/log/tor/notices.log 2>/dev/null | tail -1)
BOOTSTRAP_LINE=$(grep "Bootstrapped" /var/log/tor/notices.log 2>/dev/null | tail -1 || true)
if [ -n "$BOOTSTRAP_LINE" ]; then
BOOTSTRAP_PERCENT=$(echo "$BOOTSTRAP_LINE" | grep -oE '[0-9]+%' | tr -d '%' | tail -1)
# Extract clean integer only
BOOTSTRAP_PERCENT=$(echo "$BOOTSTRAP_LINE" | grep -oE '[0-9]+' | tail -1 | tr -d '\r' || echo 0)
BOOTSTRAP_PERCENT=${BOOTSTRAP_PERCENT:-0}
BOOTSTRAP_MESSAGE=$(echo "$BOOTSTRAP_LINE" | sed 's/.*Bootstrapped [0-9]*%[: ]*//')
fi
fi
IS_REACHABLE="false"
REACHABILITY_MESSAGE=""
if [ -f /var/log/tor/notices.log ]; then
REACHABLE_LINE=$(grep -E "reachable|self-testing" /var/log/tor/notices.log 2>/dev/null | tail -1)
if echo "$REACHABLE_LINE" | grep -q "reachable from the outside"; then
REACHABLE_LINE=$(grep -E "reachable|self-testing" /var/log/tor/notices.log 2>/dev/null | tail -1 || true)
if echo "$REACHABLE_LINE" | grep -q "reachable from the outside" 2>/dev/null; then
IS_REACHABLE="true"
REACHABILITY_MESSAGE="ORPort is reachable from the outside"
elif [ -n "$REACHABLE_LINE" ]; then
REACHABILITY_MESSAGE=$(echo "$REACHABLE_LINE" | sed 's/.*] //')
fi
fi
NICKNAME=""
FINGERPRINT=""
if [ -f /var/lib/tor/fingerprint ]; then
NICKNAME=$(awk '{print $1}' /var/lib/tor/fingerprint 2>/dev/null)
FINGERPRINT=$(awk '{print $2}' /var/lib/tor/fingerprint 2>/dev/null)
fi
ORPORT=""
DIRPORT=""
EXIT_RELAY="false"
@@ -121,7 +131,7 @@ gather_status() {
grep -qE "^BridgeRelay\s+1" /etc/tor/torrc 2>/dev/null && BRIDGE_RELAY="true"
BANDWIDTH_RATE=$(grep -E "^RelayBandwidthRate" /etc/tor/torrc 2>/dev/null | awk '{print $2,$3}')
fi
ERROR_COUNT=0
WARNING_COUNT=0
RECENT_ERRORS=""
@@ -130,32 +140,37 @@ gather_status() {
WARNING_COUNT=$(grep -cE "\[warn\]|\[warning\]" /var/log/tor/notices.log 2>/dev/null || echo 0)
RECENT_ERRORS=$(grep -E "\[err\]|\[error\]" /var/log/tor/notices.log 2>/dev/null | tail -3)
fi
VERSION_INFO=""
BUILD_TIME=""
if [ -f /build-info.txt ]; then
VERSION_INFO=$(grep "Version:" /build-info.txt 2>/dev/null | cut -d: -f2- | tr -d ' ')
BUILD_TIME=$(grep "Built:" /build-info.txt 2>/dev/null | cut -d: -f2- | tr -d ' ')
fi
PUBLIC_IP=""
PUBLIC_IP6=""
if [ "$CHECK_NETWORK" = "true" ] && command -v curl > /dev/null 2>&1; then
if [ "$CHECK_NETWORK" = "true" ] && command -v curl >/dev/null 2>&1; then
PUBLIC_IP=$(curl -4 -s --max-time 5 https://ipv4.icanhazip.com 2>/dev/null | tr -d '\r')
PUBLIC_IP6=$(curl -6 -s --max-time 5 https://ipv6.icanhazip.com 2>/dev/null | tr -d '\r')
fi
}
gather_status
# Sanitize percent and timestamp
BOOTSTRAP_PERCENT=$(echo "$BOOTSTRAP_PERCENT" | tr -cd '0-9')
BOOTSTRAP_PERCENT=${BOOTSTRAP_PERCENT:-0}
TIMESTAMP=$(date -u '+%Y-%m-%dT%H:%M:%SZ' 2>/dev/null || date '+%Y-%m-%d %H:%M:%S')
# Determine overall status safely
if [ "$IS_RUNNING" = "false" ]; then
OVERALL_STATUS="down"
elif [ "$BOOTSTRAP_PERCENT" -eq 100 ] && [ "$IS_REACHABLE" = "true" ]; then
elif is_integer "$BOOTSTRAP_PERCENT" && [ "$BOOTSTRAP_PERCENT" -eq 100 ] && [ "$IS_REACHABLE" = "true" ]; then
OVERALL_STATUS="healthy"
elif [ "$BOOTSTRAP_PERCENT" -eq 100 ]; then
elif is_integer "$BOOTSTRAP_PERCENT" && [ "$BOOTSTRAP_PERCENT" -eq 100 ]; then
OVERALL_STATUS="running"
elif [ "$BOOTSTRAP_PERCENT" -gt 0 ]; then
elif is_integer "$BOOTSTRAP_PERCENT" && [ "$BOOTSTRAP_PERCENT" -gt 0 ]; then
OVERALL_STATUS="starting"
else
OVERALL_STATUS="unknown"
@@ -163,7 +178,6 @@ fi
case "$OUTPUT_FORMAT" in
json)
cat << EOF
{
"timestamp": "$TIMESTAMP",
@@ -185,9 +199,7 @@ case "$OUTPUT_FORMAT" in
}
EOF
;;
plain)
echo "STATUS=$OVERALL_STATUS"
echo "RUNNING=$IS_RUNNING"
echo "UPTIME=$UPTIME"
@@ -202,7 +214,6 @@ EOF
echo "PUBLIC_IP=$PUBLIC_IP"
echo "PUBLIC_IP6=$PUBLIC_IP6"
;;
*)
echo "🧅 Tor Relay Status Report"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
@@ -225,10 +236,10 @@ EOF
fi
echo "🚀 Bootstrap Progress:"
if [ "$BOOTSTRAP_PERCENT" -eq 100 ]; then
if is_integer "$BOOTSTRAP_PERCENT" && [ "$BOOTSTRAP_PERCENT" -eq 100 ]; then
echo " 🟢 OK - Fully bootstrapped (100%)"
[ -n "$BOOTSTRAP_MESSAGE" ] && echo " Status: $BOOTSTRAP_MESSAGE"
elif [ "$BOOTSTRAP_PERCENT" -gt 0 ]; then
elif is_integer "$BOOTSTRAP_PERCENT" && [ "$BOOTSTRAP_PERCENT" -gt 0 ]; then
echo " 🔄 Bootstrapping: $BOOTSTRAP_PERCENT%"
[ -n "$BOOTSTRAP_MESSAGE" ] && echo " Status: $BOOTSTRAP_MESSAGE"
else

View File

@@ -5,7 +5,7 @@
set -e
# Configuration
VERSION="1.1.0"
VERSION="1.0.9"
LOG_FILE="${LOG_FILE:-/var/log/tor/notices.log}"
LOG_LINES="${LOG_LINES:-50}"
FOLLOW_MODE="${FOLLOW_MODE:-false}"
@@ -185,6 +185,7 @@ if [ "$FILTER_MODE" = "all" ]; then
echo "📊 Stats: $TOTAL_LINES total | $ERROR_COUNT errors | $WARNING_COUNT warnings"
fi
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""