Skip to main content

Early exit pattern matching for command output with fast error detection

Project description

earlyexit ๐Ÿš€

Early exit pattern matching for command output - Exit immediately when a pattern is matched, with timeout support.

Implements the early error detection pattern for faster feedback during long-running commands, CI/CD pipelines, and log monitoring.

๐ŸŽฏ Purpose

Traditional grep processes the entire input stream. earlyexit exits immediately on the first match, saving time and providing instant feedback for errors.

Perfect for:

  • ๐Ÿ”ง Long-running build processes
  • ๐Ÿงช Test suites
  • ๐Ÿš€ Deployment pipelines
  • ๐Ÿ“Š Log monitoring
  • โฑ๏ธ Time-sensitive operations

๐Ÿ“ฆ Installation

# Install from PyPI (when published)
pip install earlyexit

# Install from source
git clone https://github.com/rsleedbx/earlyexit
cd earlyexit
pip install -e .

# With Perl-compatible regex support
pip install -e ".[perl]"

๐Ÿš€ Quick Start

# Exit immediately on first error (with 30s timeout)
long_running_command | earlyexit -t 30 'Error|Failed'

# Monitor Terraform apply
terraform apply | earlyexit -t 600 -i 'error'

# Stop after 3 test failures
pytest | earlyexit -m 3 'FAILED'

# Check if service is healthy (invert match)
health_check_loop | earlyexit -v 'OK' -t 10

๐Ÿ“š Usage

earlyexit [OPTIONS] PATTERN

Arguments:
  PATTERN                Regular expression pattern to match

Options:
  -t, --timeout SECONDS  Timeout in seconds (default: no timeout)
  -m, --max-count NUM    Stop after NUM matches (default: 1)
  -i, --ignore-case      Case-insensitive matching
  -E, --extended-regexp  Extended regex (Python re module, default)
  -P, --perl-regexp      Perl-compatible regex (requires regex module)
  -v, --invert-match     Invert match - select non-matching lines
  -q, --quiet            Quiet mode - suppress output, only exit code
  -n, --line-number      Prefix output with line number
  --color WHEN           Colorize output: always, auto (default), never
  --version              Show version
  -h, --help             Show help message

Exit Codes:
  0 - Pattern matched (error detected)
  1 - No match found (success)
  2 - Timeout exceeded
  3 - Other error

๐Ÿ’ก Examples

Example 1: Terraform Operations

# Exit immediately on error, 10min timeout
terraform apply -auto-approve 2>&1 | \
  stdbuf -o0 tee terraform.log | \
  earlyexit -t 600 -i 'error'

if [ $? -eq 0 ]; then
  echo "โŒ Terraform failed - check terraform.log"
  exit 1
elif [ $? -eq 2 ]; then
  echo "โฑ๏ธ  Terraform timed out after 10 minutes"
  exit 2
else
  echo "โœ… Terraform completed successfully"
fi

Example 2: Database Provisioning

# Monitor database creation, fail fast on errors
vapordb create --cloud aws --db mysql 2>&1 | \
  tee /tmp/db_create.log | \
  earlyexit -t 1800 'Error|Failed|Exception'

case $? in
  0) echo "โŒ Database creation failed"; exit 1 ;;
  1) echo "โœ… Database created successfully" ;;
  2) echo "โฑ๏ธ  Creation timed out after 30 minutes"; exit 2 ;;
esac

Example 3: Test Suite Monitoring

# Stop after 5 test failures
pytest -v | earlyexit -m 5 'FAILED'

if [ $? -eq 0 ]; then
  echo "โŒ Tests failed - stopping early"
  exit 1
fi

Example 4: CI/CD Pipeline

# Monitor build output for errors
./build.sh 2>&1 | \
  stdbuf -o0 tee build.log | \
  earlyexit -t 3600 -iE '(error|fatal|exception)'

exit $?  # Propagate exit code

Example 5: Log Monitoring

# Monitor application logs in real-time
tail -f /var/log/app.log | \
  earlyexit -t 300 -i 'error|exception|fatal'

if [ $? -eq 0 ]; then
  echo "๐Ÿšจ Error detected in logs!"
  # Send alert, trigger remediation, etc.
fi

Example 6: Health Check

# Ensure service stays healthy for 60 seconds
# Exit if "OK" stops appearing (invert match)
while true; do
  curl -s http://localhost:8080/health
  sleep 1
done | earlyexit -v 'OK' -t 60

if [ $? -eq 0 ]; then
  echo "โŒ Health check failed - 'OK' not found"
  exit 1
fi

Example 7: Multiple Patterns

# Match any of several error conditions
app_command | earlyexit -E '(ERROR|FATAL|EXCEPTION|SEGFAULT|PANIC)'

Example 8: With Line Numbers

# Show line numbers for matched errors
long_log_file | earlyexit -n -i 'error'
# Output: 1234:ERROR: Connection failed

๐Ÿ” Pattern Syntax

Extended Regex (-E, default)

Uses Python's re module (similar to grep -E):

# Multiple alternatives
earlyexit 'error|warning|fatal'

# Character classes
earlyexit '[Ee]rror'

# Quantifiers
earlyexit 'fail(ed|ure)?'

# Word boundaries
earlyexit '\berror\b'

Perl-Compatible Regex (-P)

Requires regex module (pip install earlyexit[perl]):

# Lookaheads/lookbehinds
earlyexit -P '(?<=ERROR: ).*'

# Named groups
earlyexit -P '(?P<level>ERROR|WARN): (?P<msg>.*)'

# Recursive patterns
earlyexit -P '\(((?:[^()]++|(?R))*+)\)'

๐ŸŽฏ Use Cases

1. Fast Feedback in CI/CD

Stop the build immediately on first error instead of waiting for full completion:

# GitLab CI example
script:
  - make build 2>&1 | earlyexit -t 3600 'error' || exit 1

2. Cost Optimization

Save compute costs by stopping failed cloud operations early:

# Stop provisioning if errors detected in first 5 minutes
terraform apply | earlyexit -t 300 'Error:' && terraform destroy -auto-approve

3. Development Workflow

Get instant feedback during development:

# Watch for compilation errors
npm run watch | earlyexit 'ERROR'

4. Monitoring & Alerting

Detect issues in production logs:

# Alert on first critical error
kubectl logs -f pod-name | earlyexit 'CRITICAL' && send-alert

โšก Performance Comparison

Tool Behavior Time to Detect Error
grep Processes entire input After full completion
grep -m 1 Stops after first match Immediate (but no timeout)
earlyexit Stops after first match + timeout Immediate + safety net

Real-World Example

# Command that takes 30 minutes but fails at 5 minutes

# grep: Waits full 30 minutes
command | grep 'Error'  # 30 minutes wasted

# earlyexit: Exits at 5 minutes
command | earlyexit -t 1800 'Error'  # Saves 25 minutes!

๐Ÿ”ง Integration with Other Tools

With tee (save logs + monitor)

command 2>&1 | stdbuf -o0 tee output.log | earlyexit -t 300 'Error'

With timeout (double safety)

timeout 600 bash << 'EOF'
  command 2>&1 | stdbuf -o0 tee log.txt | earlyexit -t 300 'Error'
EOF

With stdbuf (unbuffered output)

command 2>&1 | stdbuf -o0 tee log.txt | earlyexit 'Error'

๐Ÿงช Testing

# Test success (no match)
echo "Starting..." | earlyexit 'Error'  # Exit 1

# Test match (immediate exit)
echo "Error detected" | earlyexit 'Error'  # Exit 0

# Test timeout
sleep 10 | earlyexit -t 2 'Error'  # Exit 2 after 2 seconds

# Test case-insensitive
echo "ERROR" | earlyexit -i 'error'  # Exit 0

# Test max count
printf "Error\nError\nError\n" | earlyexit -m 2 'Error'  # Exit 0 after 2 matches

# Test invert match
echo "OK" | earlyexit -v 'Error'  # Exit 1 (OK is not Error)
echo "Error" | earlyexit -v 'OK'  # Exit 0 (Error doesn't match OK)

๐Ÿ“Š Exit Codes

Exit Code Meaning Use Case
0 Pattern matched Error detected - fail fast
1 No match Success - continue
2 Timeout Command took too long
3 Error Invalid pattern, broken pipe, etc.
130 Interrupted Ctrl+C pressed

๐Ÿ”„ Comparison with grep

Feature grep grep -m 1 earlyexit
Pattern matching โœ… โœ… โœ…
Extended regex โœ… -E โœ… -E โœ… -E
Perl regex โœ… -P โœ… -P โœ… -P (with regex module)
Stop on first match โŒ โœ… โœ…
Timeout โŒ โŒ โœ… -t
Exit code clarity โš ๏ธ Complex โš ๏ธ Complex โœ… Simple (0/1/2/3)
Max count โŒ โœ… -m โœ… -m
Invert match โœ… -v โœ… -v โœ… -v
Color output โœ… โœ… โœ… --color
Line numbers โœ… -n โœ… -n โœ… -n

๐Ÿ› Troubleshooting

Pattern not matching?

# Test your pattern separately
echo "test string" | earlyexit 'pattern'

# Enable line numbers to see what's being processed
command | earlyexit -n 'pattern'

# Use -i for case-insensitive if needed
command | earlyexit -i 'pattern'

Timeout not working?

# Ensure timeout is numeric
earlyexit -t 10 'pattern'  # โœ… Correct
earlyexit -t 10s 'pattern'  # โŒ Wrong - no 's' suffix

Buffering issues?

# Use stdbuf to disable buffering
command 2>&1 | stdbuf -o0 tee log.txt | earlyexit 'pattern'

๐ŸŽ“ Best Practices

  1. Always use timeout for long-running commands:

    command | earlyexit -t 600 'Error'  # โœ… Good
    command | earlyexit 'Error'          # โš ๏ธ Risky - no timeout
    
  2. Save logs with tee:

    command 2>&1 | stdbuf -o0 tee log.txt | earlyexit -t 300 'Error'
    
  3. Use case-insensitive for error detection:

    earlyexit -i 'error'  # Matches Error, ERROR, error
    
  4. Multiple patterns with extended regex:

    earlyexit -E '(error|warning|fatal|exception)'
    
  5. Check exit codes properly:

    command | earlyexit 'Error'
    case $? in
      0) echo "Error detected"; exit 1 ;;
      1) echo "Success" ;;
      2) echo "Timeout"; exit 2 ;;
      *) echo "Unexpected error"; exit 3 ;;
    esac
    

๐Ÿ“ License

MIT License - see LICENSE file for details

๐Ÿค Contributing

Contributions welcome! Please open an issue or PR on GitHub.

๐Ÿ”— Related Projects

  • timeout - Command timeout utility (part of GNU coreutils)
  • stdbuf - Modify buffering of streams (part of GNU coreutils)
  • ripgrep (rg) - Fast grep alternative in Rust

๐Ÿ“ฎ Contact

Robert Lee - robert.lee@databricks.com


Made with โค๏ธ for developers who value fast feedback

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

earlyexit-0.0.1.tar.gz (11.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

earlyexit-0.0.1-py3-none-any.whl (9.2 kB view details)

Uploaded Python 3

File details

Details for the file earlyexit-0.0.1.tar.gz.

File metadata

  • Download URL: earlyexit-0.0.1.tar.gz
  • Upload date:
  • Size: 11.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.18

File hashes

Hashes for earlyexit-0.0.1.tar.gz
Algorithm Hash digest
SHA256 7f420cf1017f40211301bd710fb7a6e565e4f4d556706e31a323393b65921fc5
MD5 7e2355e92ab7de6ce40168cc3574828c
BLAKE2b-256 04002648c1b00c27859043ae4baf403e926495d93da51d914dd81f20fc77418f

See more details on using hashes here.

File details

Details for the file earlyexit-0.0.1-py3-none-any.whl.

File metadata

  • Download URL: earlyexit-0.0.1-py3-none-any.whl
  • Upload date:
  • Size: 9.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.18

File hashes

Hashes for earlyexit-0.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 cdffeb28eaf0404213d9b5daaf5543fed4450f9d7775725f30b825934076bf67
MD5 3035a572d073feedf9af3ba9bcdce2a1
BLAKE2b-256 0ae72d82da8e92dba27ed0a53c6d6d3d9fde1ca54d056689171c96874cbe276d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page