Tutorial

Neue Updates und Verbesserungen zu Macfleet.

Wichtiger Hinweis

Die in diesen Tutorials bereitgestellten Codebeispiele und Skripte dienen nur zu Bildungszwecken. Macfleet ist nicht verantwortlich für Probleme, Schäden oder Sicherheitslücken, die durch die Verwendung, Änderung oder Implementierung dieser Beispiele entstehen können. Überprüfen und testen Sie Code immer in einer sicheren Umgebung, bevor Sie ihn in Produktionssystemen verwenden.

Application Force Close Management for macOS

Implement enterprise-grade application force close management across your MacFleet deployment with automated process termination, security validation, troubleshooting diagnostics, and comprehensive fleet-wide application control. This tutorial provides solutions for maintaining system stability while ensuring secure and efficient application process management.

Understanding macOS Application Process Management

macOS provides several methods for process termination:

  • killall - Terminate all instances of a named process
  • kill - Terminate specific processes by PID
  • pkill - Pattern-based process termination
  • Activity Monitor - GUI-based process management
  • Force Quit - System-level application termination

Basic Force Close Operations

Simple Force Close

#!/bin/bash

# Basic force close
killall "appname"

Force Close with Verbose Output

#!/bin/bash

# Force close with PID output
killall -v "Notes"

Detailed Process Information

#!/bin/bash

# Get detailed process info without killing
killall -d "appname"

List Available Signals

#!/bin/bash

# List available signals
killall -l "appname"

Force Close with Specific Signal

#!/bin/bash

# Force close with ABRT signal
killall -abrt "Pages"

Enterprise Application Force Close Management System

Comprehensive Process Control Tool

#!/bin/bash

# MacFleet Enterprise Application Force Close Management Tool
# Advanced process termination and application control

# Configuration
CONFIG_FILE="/etc/macfleet/force_close_policy.conf"
LOG_FILE="/var/log/macfleet_force_close.log"
QUARANTINE_DIR="/Library/MacFleet/TerminatedApps"
AUDIT_LOG="/var/log/macfleet_process_audit.log"

# Create directories
mkdir -p "$(dirname "$CONFIG_FILE")" "$(dirname "$LOG_FILE")" "$QUARANTINE_DIR" "$(dirname "$AUDIT_LOG")"

# Default force close management policy
cat > "$CONFIG_FILE" 2>/dev/null << 'EOF' || true
# MacFleet Enterprise Application Force Close Management Policy
# Version: 2.0

# Force Close Policy Enforcement
ENFORCE_FORCE_CLOSE_POLICIES=true
GRACEFUL_TERMINATION_FIRST=true
ESCALATION_TIMEOUT=10
SAVE_WORK_BEFORE_TERMINATION=true
PREVENT_SYSTEM_PROCESS_TERMINATION=true

# Security and Safety
REQUIRE_ADMIN_APPROVAL=false
VALIDATE_PROCESS_LEGITIMACY=true
CHECK_PROCESS_DEPENDENCIES=true
MALWARE_DETECTION_ENABLED=true
SUSPICIOUS_BEHAVIOR_MONITORING=true

# Business Rules
BUSINESS_HOURS_PROTECTION=true
BUSINESS_HOURS_START="09:00"
BUSINESS_HOURS_END="18:00"
CRITICAL_APP_PROTECTION=true
PRODUCTIVITY_APP_MONITORING=true

# Diagnostic and Troubleshooting
DIAGNOSTIC_LOGGING=true
CRASH_REPORT_COLLECTION=true
PERFORMANCE_MONITORING=true
RESOURCE_USAGE_TRACKING=true
HANG_DETECTION_ENABLED=true

# Notification and Communication
USER_NOTIFICATION_ENABLED=true
ADMIN_NOTIFICATION_ENABLED=true
SLACK_WEBHOOK_URL=""
EMAIL_NOTIFICATION_ENABLED=false
FORCE_CLOSE_WARNINGS=true

# Compliance and Audit
AUDIT_ALL_TERMINATIONS=true
COMPLIANCE_REPORTING=true
INCIDENT_DOCUMENTATION=true
ESCALATION_PROCEDURES=true
AUTOMATED_RECOVERY=true

# Recovery and Restart
AUTO_RESTART_CRITICAL_APPS=true
RESTART_DELAY=5
CRASH_RECOVERY_ENABLED=true
STATE_PRESERVATION=true
USER_SESSION_PROTECTION=true
EOF

# Source configuration
source "$CONFIG_FILE" 2>/dev/null || true

# Logging function
log_action() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
}

# Audit logging function
audit_log() {
    local action="$1"
    local process_name="$2"
    local result="$3"
    local details="$4"
    echo "$(date '+%Y-%m-%d %H:%M:%S') - ACTION:$action PROCESS:$process_name RESULT:$result DETAILS:$details USER:$(whoami)" >> "$AUDIT_LOG"
}

# Get comprehensive process information
get_process_info() {
    local process_name="$1"
    
    echo "=== Process Information Analysis ==="
    
    # Check if process exists
    if ! pgrep -f "$process_name" >/dev/null 2>&1; then
        echo "Process not found: $process_name"
        return 1
    fi
    
    # Get process details
    echo "Process Name: $process_name"
    
    # Get PIDs
    local pids
    pids=$(pgrep -f "$process_name" | tr '\n' ' ')
    echo "Process IDs: $pids"
    
    # Get CPU and memory usage
    echo "Resource Usage:"
    ps -p $(pgrep -f "$process_name" | head -1) -o pid,pcpu,pmem,time,command 2>/dev/null | tail -1
    
    # Get process tree
    echo "Process Tree:"
    pstree $(pgrep -f "$process_name" | head -1) 2>/dev/null || echo "  Process tree not available"
    
    # Get open files
    echo "Open Files Count:"
    lsof -p $(pgrep -f "$process_name" | head -1) 2>/dev/null | wc -l || echo "  Unable to determine"
    
    # Get network connections
    echo "Network Connections:"
    lsof -i -p $(pgrep -f "$process_name" | head -1) 2>/dev/null | wc -l || echo "  0"
    
    # Check if process is hanging
    local cpu_usage
    cpu_usage=$(ps -p $(pgrep -f "$process_name" | head -1) -o pcpu= 2>/dev/null | xargs)
    if [[ -n "$cpu_usage" ]] && (( $(echo "$cpu_usage < 0.1" | bc -l) )); then
        echo "Status: Potentially hung (very low CPU usage)"
    else
        echo "Status: Active"
    fi
}

# Check if process termination is safe
check_termination_safety() {
    local process_name="$1"
    local force="${2:-false}"
    
    echo "=== Validating Process Termination Safety ==="
    
    # Check if process exists
    if ! pgrep -f "$process_name" >/dev/null 2>&1; then
        echo "✅ Process not running: $process_name"
        return 0
    fi
    
    # Prevent system process termination
    if [[ "$PREVENT_SYSTEM_PROCESS_TERMINATION" == "true" ]]; then
        local system_processes=(
            "kernel"
            "launchd"
            "WindowServer"
            "loginwindow"
            "SystemUIServer"
            "Dock"
            "Finder"
            "cfprefsd"
            "CoreServicesUIAgent"
        )
        
        for system_process in "${system_processes[@]}"; do
            if [[ "$process_name" == "$system_process" ]]; then
                echo "❌ Cannot terminate critical system process: $process_name"
                audit_log "TERMINATION_BLOCKED" "$process_name" "SYSTEM_PROCESS" "System process protection active"
                return 1
            fi
        done
    fi
    
    # Business hours protection for critical apps
    if [[ "$BUSINESS_HOURS_PROTECTION" == "true" && "$force" != "true" ]]; then
        local current_hour
        current_hour=$(date +%H)
        local start_hour
        start_hour=$(echo "$BUSINESS_HOURS_START" | cut -d':' -f1)
        local end_hour
        end_hour=$(echo "$BUSINESS_HOURS_END" | cut -d':' -f1)
        
        if [[ $current_hour -ge $start_hour && $current_hour -lt $end_hour ]]; then
            local critical_apps=(
                "Microsoft Word"
                "Microsoft Excel"
                "Microsoft PowerPoint"
                "Slack"
                "Microsoft Teams"
                "Zoom"
                "Safari"
                "Google Chrome"
            )
            
            for critical_app in "${critical_apps[@]}"; do
                if [[ "$process_name" == *"$critical_app"* ]]; then
                    echo "❌ Termination blocked: Critical productivity app during business hours"
                    audit_log "TERMINATION_BLOCKED" "$process_name" "BUSINESS_HOURS" "Critical app protection during business hours"
                    return 1
                fi
            done
        fi
    fi
    
    # Check for unsaved work
    if [[ "$SAVE_WORK_BEFORE_TERMINATION" == "true" ]]; then
        echo "⚠️  Checking for unsaved work..."
        
        # Check for document apps with potential unsaved changes
        local document_apps=(
            "TextEdit"
            "Pages"
            "Numbers"
            "Keynote"
            "Microsoft Word"
            "Microsoft Excel"
            "Microsoft PowerPoint"
        )
        
        for doc_app in "${document_apps[@]}"; do
            if [[ "$process_name" == *"$doc_app"* ]]; then
                echo "📝 Document application detected - attempting to save work"
                try_save_work "$process_name"
                break
            fi
        done
    fi
    
    # Check process dependencies
    if [[ "$CHECK_PROCESS_DEPENDENCIES" == "true" ]]; then
        local child_processes
        child_processes=$(pgrep -P $(pgrep -f "$process_name" | head -1) 2>/dev/null | wc -l)
        
        if [[ $child_processes -gt 0 ]]; then
            echo "⚠️  Process has $child_processes child processes"
            if [[ "$force" != "true" ]]; then
                echo "❌ Termination blocked: Process has dependencies. Use force option to proceed."
                audit_log "TERMINATION_BLOCKED" "$process_name" "DEPENDENCIES" "Process has $child_processes child processes"
                return 1
            fi
        fi
    fi
    
    echo "✅ Process termination safety validated"
    audit_log "SAFETY_CHECK" "$process_name" "PASSED" "All safety checks passed"
    return 0
}

# Try to save work in document applications
try_save_work() {
    local process_name="$1"
    
    echo "=== Attempting to Save Work ==="
    
    # Send save command via AppleScript for common applications
    local save_commands=(
        "osascript -e 'tell application \"System Events\" to keystroke \"s\" using command down'"
        "osascript -e 'tell application \"$process_name\" to save every document'"
    )
    
    for cmd in "${save_commands[@]}"; do
        eval "$cmd" 2>/dev/null || true
        sleep 1
    done
    
    # Wait a moment for save operations to complete
    sleep 3
    
    echo "💾 Save attempt completed"
    log_action "Work save attempt completed for $process_name"
}

# Detect suspicious or malware processes
detect_suspicious_process() {
    local process_name="$1"
    
    if [[ "$MALWARE_DETECTION_ENABLED" != "true" ]]; then
        return 0
    fi
    
    echo "=== Suspicious Process Detection ==="
    
    local suspicious_indicators=(
        "crypto"
        "miner"
        "trojan"
        "virus"
        "malware"
        "ransomware"
        "keylogger"
        "backdoor"
    )
    
    # Check process name for suspicious keywords
    for indicator in "${suspicious_indicators[@]}"; do
        if [[ "$process_name" == *"$indicator"* ]]; then
            echo "🚨 Suspicious process detected: $process_name (matches: $indicator)"
            log_action "SECURITY ALERT: Suspicious process detected: $process_name"
            audit_log "SUSPICIOUS_PROCESS" "$process_name" "DETECTED" "Matches indicator: $indicator"
            
            # Quarantine process information
            quarantine_process_info "$process_name"
            return 1
        fi
    done
    
    # Check for unusual resource consumption
    local cpu_usage
    cpu_usage=$(ps -p $(pgrep -f "$process_name" | head -1) -o pcpu= 2>/dev/null | xargs)
    
    if [[ -n "$cpu_usage" ]] && (( $(echo "$cpu_usage > 80" | bc -l) )); then
        echo "⚠️  High CPU usage detected: ${cpu_usage}%"
        log_action "High CPU usage detected for $process_name: ${cpu_usage}%"
    fi
    
    return 0
}

# Quarantine suspicious process information
quarantine_process_info() {
    local process_name="$1"
    
    echo "=== Quarantining Process Information ==="
    
    local quarantine_file="$QUARANTINE_DIR/suspicious_process_$(date +%Y%m%d_%H%M%S).json"
    
    mkdir -p "$QUARANTINE_DIR"
    
    # Gather comprehensive process information
    local pid
    pid=$(pgrep -f "$process_name" | head -1)
    
    cat > "$quarantine_file" << EOF
{
  "timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
  "process_name": "$process_name",
  "pid": "$pid",
  "detection_reason": "suspicious_indicators",
  "system_info": {
    "hostname": "$(hostname)",
    "user": "$(whoami)",
    "os_version": "$(sw_vers -productVersion)"
  },
  "process_details": {
    "command_line": "$(ps -p $pid -o command= 2>/dev/null || echo 'unknown')",
    "cpu_usage": "$(ps -p $pid -o pcpu= 2>/dev/null || echo 'unknown')",
    "memory_usage": "$(ps -p $pid -o pmem= 2>/dev/null || echo 'unknown')",
    "start_time": "$(ps -p $pid -o lstart= 2>/dev/null || echo 'unknown')"
  }
}
EOF
    
    echo "🔒 Process information quarantined: $quarantine_file"
    log_action "Suspicious process information quarantined: $quarantine_file"
}

# Send termination notification
send_termination_notification() {
    local process_name="$1"
    local operation="$2"
    local result="$3"
    local reason="$4"
    
    if [[ "$USER_NOTIFICATION_ENABLED" != "true" ]]; then
        return 0
    fi
    
    echo "=== Sending Termination Notifications ==="
    
    local notification_title="MacFleet Process Management"
    local notification_message="Process $operation: $process_name ($result)"
    
    if [[ -n "$reason" ]]; then
        notification_message="$notification_message - Reason: $reason"
    fi
    
    # Display notification to logged-in users
    local logged_users
    logged_users=$(who | awk '{print $1}' | sort -u)
    
    for user in $logged_users; do
        if [[ -n "$user" ]]; then
            sudo -u "$user" osascript -e "display notification \"$notification_message\" with title \"$notification_title\"" 2>/dev/null || true
            echo "📱 Notification sent to user: $user"
        fi
    done
    
    # Slack notification
    if [[ -n "$SLACK_WEBHOOK_URL" ]]; then
        local slack_payload="{\"text\":\"🖥️ *$(hostname)*: $notification_title\\n$notification_message\"}"
        curl -s -X POST -H 'Content-type: application/json' --data "$slack_payload" "$SLACK_WEBHOOK_URL" >/dev/null 2>&1 || true
        echo "📢 Slack notification sent"
    fi
    
    log_action "Termination notifications sent for $process_name ($operation - $result)"
}

# Enterprise force close with escalation
enterprise_force_close() {
    local process_name="$1"
    local force="${2:-false}"
    local signal="${3:-TERM}"
    
    echo "=== Enterprise Force Close Initiated ==="
    
    if [[ -z "$process_name" ]]; then
        echo "❌ Process name required"
        return 1
    fi
    
    # Get process information
    echo "Analyzing process: $process_name"
    get_process_info "$process_name"
    
    # Detect suspicious processes
    if detect_suspicious_process "$process_name"; then
        echo "⚠️  Suspicious process detected - proceeding with caution"
    fi
    
    # Safety checks
    if ! check_termination_safety "$process_name" "$force"; then
        return 1
    fi
    
    log_action "ENTERPRISE FORCE CLOSE: Starting termination of $process_name"
    audit_log "FORCE_CLOSE" "$process_name" "INITIATED" "Signal: $signal Force: $force"
    
    # Graceful termination first (if enabled)
    if [[ "$GRACEFUL_TERMINATION_FIRST" == "true" && "$force" != "true" ]]; then
        echo "🔄 Attempting graceful termination first..."
        
        if killall -TERM "$process_name" 2>/dev/null; then
            echo "Graceful termination signal sent, waiting ${ESCALATION_TIMEOUT}s..."
            sleep "$ESCALATION_TIMEOUT"
            
            # Check if process is still running
            if ! pgrep -f "$process_name" >/dev/null 2>&1; then
                echo "✅ Process terminated gracefully"
                send_termination_notification "$process_name" "graceful termination" "success"
                audit_log "FORCE_CLOSE" "$process_name" "SUCCESS" "Graceful termination successful"
                return 0
            else
                echo "⚠️  Graceful termination failed, escalating to force termination"
            fi
        fi
    fi
    
    # Force termination
    echo "🚨 Executing force termination..."
    
    case "$signal" in
        "TERM")
            if killall "$process_name" 2>/dev/null; then
                echo "✅ Process force closed successfully with TERM signal"
                termination_result="success"
            else
                echo "❌ Failed to force close process with TERM signal"
                termination_result="failed"
            fi
            ;;
        "KILL")
            if killall -KILL "$process_name" 2>/dev/null; then
                echo "✅ Process force killed successfully with KILL signal"
                termination_result="success"
            else
                echo "❌ Failed to force kill process with KILL signal"
                termination_result="failed"
            fi
            ;;
        "ABRT")
            if killall -ABRT "$process_name" 2>/dev/null; then
                echo "✅ Process aborted successfully with ABRT signal"
                termination_result="success"
            else
                echo "❌ Failed to abort process with ABRT signal"
                termination_result="failed"
            fi
            ;;
        *)
            if killall -"$signal" "$process_name" 2>/dev/null; then
                echo "✅ Process terminated successfully with $signal signal"
                termination_result="success"
            else
                echo "❌ Failed to terminate process with $signal signal"
                termination_result="failed"
            fi
            ;;
    esac
    
    # Send notifications
    send_termination_notification "$process_name" "force close" "$termination_result" "Signal: $signal"
    
    # Auto-restart critical applications if configured
    if [[ "$AUTO_RESTART_CRITICAL_APPS" == "true" && "$termination_result" == "success" ]]; then
        restart_if_critical "$process_name"
    fi
    
    if [[ "$termination_result" == "success" ]]; then
        log_action "Process force closed successfully: $process_name"
        audit_log "FORCE_CLOSE" "$process_name" "SUCCESS" "Signal: $signal"
        return 0
    else
        log_action "FAILED: Could not force close process: $process_name"
        audit_log "FORCE_CLOSE" "$process_name" "FAILED" "Signal: $signal"
        return 1
    fi
}

# Restart critical applications
restart_if_critical() {
    local process_name="$1"
    
    local critical_apps=(
        "Finder"
        "Dock"
        "SystemUIServer"
        "Spotlight"
    )
    
    for critical_app in "${critical_apps[@]}"; do
        if [[ "$process_name" == *"$critical_app"* ]]; then
            echo "🔄 Restarting critical application: $critical_app"
            log_action "Auto-restarting critical application: $critical_app"
            
            sleep "$RESTART_DELAY"
            
            case "$critical_app" in
                "Finder")
                    open -a Finder &
                    ;;
                "Dock")
                    killall Dock &
                    ;;
                "SystemUIServer")
                    killall SystemUIServer &
                    ;;
                "Spotlight")
                    mdutil -E / &
                    ;;
            esac
            
            break
        fi
    done
}

# Bulk force close operations
bulk_force_close() {
    local process_list_file="$1"
    local force="${2:-false}"
    local signal="${3:-TERM}"
    
    echo "=== Bulk Force Close Operations ==="
    
    if [[ ! -f "$process_list_file" ]]; then
        echo "❌ Process list file not found: $process_list_file"
        return 1
    fi
    
    local success_count=0
    local failure_count=0
    local total_count=0
    
    while IFS= read -r process_name; do
        # Skip empty lines and comments
        if [[ -z "$process_name" || "$process_name" == \#* ]]; then
            continue
        fi
        
        ((total_count++))
        echo "Processing ($total_count): $process_name"
        
        if enterprise_force_close "$process_name" "$force" "$signal"; then
            ((success_count++))
        else
            ((failure_count++))
        fi
        
        echo "---"
        sleep 1  # Brief pause between operations
    done < "$process_list_file"
    
    echo "=== Bulk Force Close Summary ==="
    echo "Total processes: $total_count"
    echo "Successful terminations: $success_count"
    echo "Failed terminations: $failure_count"
    
    log_action "Bulk force close completed: $success_count/$total_count successful"
    audit_log "BULK_FORCE_CLOSE" "MULTIPLE" "COMPLETED" "Success: $success_count Failed: $failure_count Total: $total_count Signal: $signal"
}

# Hang detection and automatic recovery
detect_and_recover_hangs() {
    echo "=== Hang Detection and Recovery ==="
    
    if [[ "$HANG_DETECTION_ENABLED" != "true" ]]; then
        echo "Hang detection is disabled"
        return 0
    fi
    
    local hang_threshold=0.1  # CPU usage below this for extended time indicates hang
    local hang_duration=30    # Seconds of low activity to consider hung
    
    # Find processes with very low CPU usage
    local potentially_hung
    potentially_hung=$(ps -A -o pid,pcpu,time,command | awk -v threshold="$hang_threshold" '$2 < threshold && $2 > 0 {print $1 ":" $4}')
    
    if [[ -n "$potentially_hung" ]]; then
        echo "Potentially hung processes detected:"
        echo "$potentially_hung" | while IFS=':' read -r pid command; do
            echo "  PID $pid: $command"
            
            # Check if it's a user application (not system process)
            if [[ "$command" == *".app"* ]]; then
                local app_name
                app_name=$(basename "$command")
                echo "🔄 Attempting recovery of hung application: $app_name"
                
                log_action "Hang detected and recovery attempted: $app_name (PID: $pid)"
                audit_log "HANG_RECOVERY" "$app_name" "ATTEMPTED" "PID: $pid"
                
                # Try graceful recovery first
                kill -USR1 "$pid" 2>/dev/null || true
                sleep 5
                
                # If still hanging, force close
                if ps -p "$pid" >/dev/null 2>&1; then
                    enterprise_force_close "$app_name" "true" "TERM"
                fi
            fi
        done
    else
        echo "No hung processes detected"
    fi
}

# Generate comprehensive process management report
generate_process_report() {
    local report_file="/Library/MacFleet/Reports/process_management_report_$(date +%Y%m%d_%H%M%S).json"
    
    echo "=== Generating Process Management Report ==="
    
    mkdir -p "$(dirname "$report_file")"
    
    # Count recent operations from audit log
    local recent_terminations=0
    local recent_hangs=0
    local suspicious_processes=0
    
    if [[ -f "$AUDIT_LOG" ]]; then
        recent_terminations=$(grep -c "ACTION:FORCE_CLOSE.*RESULT:SUCCESS" "$AUDIT_LOG" 2>/dev/null || echo 0)
        recent_hangs=$(grep -c "ACTION:HANG_RECOVERY" "$AUDIT_LOG" 2>/dev/null || echo 0)
        suspicious_processes=$(grep -c "ACTION:SUSPICIOUS_PROCESS" "$AUDIT_LOG" 2>/dev/null || echo 0)
    fi
    
    # Get current system load
    local load_average
    load_average=$(uptime | awk -F'load average:' '{print $2}' | awk '{print $1}' | tr -d ',')
    
    # Count running processes
    local total_processes
    total_processes=$(ps -A | wc -l)
    
    # Create JSON report
    cat > "$report_file" << EOF
{
  "report_type": "process_management",
  "timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
  "device_info": {
    "hostname": "$(hostname)",
    "os_version": "$(sw_vers -productVersion)",
    "serial_number": "$(system_profiler SPHardwareDataType | grep "Serial Number" | awk -F: '{print $2}' | xargs)"
  },
  "system_status": {
    "load_average": "$load_average",
    "total_processes": $total_processes,
    "recent_terminations": $recent_terminations,
    "hang_recoveries": $recent_hangs,
    "suspicious_processes_detected": $suspicious_processes
  },
  "policy_configuration": {
    "graceful_termination_first": $GRACEFUL_TERMINATION_FIRST,
    "business_hours_protection": $BUSINESS_HOURS_PROTECTION,
    "hang_detection_enabled": $HANG_DETECTION_ENABLED,
    "malware_detection_enabled": $MALWARE_DETECTION_ENABLED
  },
  "security_status": {
    "system_process_protection": $PREVENT_SYSTEM_PROCESS_TERMINATION,
    "suspicious_behavior_monitoring": $SUSPICIOUS_BEHAVIOR_MONITORING,
    "audit_enabled": $AUDIT_ALL_TERMINATIONS
  }
}
EOF
    
    echo "Process management report saved to: $report_file"
    log_action "Process management report generated: $report_file"
}

# Main function with argument handling
main() {
    log_action "=== MacFleet Process Management Tool Started ==="
    
    case "${1:-help}" in
        "close")
            enterprise_force_close "$2" "$3" "$4"
            ;;
        "bulk")
            bulk_force_close "$2" "$3" "$4"
            ;;
        "info")
            get_process_info "$2"
            ;;
        "detect-hangs")
            detect_and_recover_hangs
            ;;
        "report")
            generate_process_report
            ;;
        *)
            echo "MacFleet Enterprise Application Force Close Management Tool"
            echo "Usage: $0 [command] [options]"
            echo ""
            echo "Commands:"
            echo "  close [process_name] [force] [signal]    - Force close application with safety checks"
            echo "  bulk [list_file] [force] [signal]       - Bulk force close from file list"
            echo "  info [process_name]                     - Get detailed process information"
            echo "  detect-hangs                            - Detect and recover hung applications"
            echo "  report                                  - Generate process management report"
            echo ""
            echo "Signals:"
            echo "  TERM (default)  - Graceful termination signal"
            echo "  KILL           - Immediate termination (cannot be ignored)"
            echo "  ABRT           - Abort with core dump generation"
            echo "  HUP            - Hang up signal"
            echo "  INT            - Interrupt signal"
            echo ""
            echo "Examples:"
            echo "  $0 close \"Safari\"                      - Safe force close of Safari"
            echo "  $0 close \"Notes\" true KILL             - Force kill Notes (bypass safety)"
            echo "  $0 bulk hung_processes.txt              - Bulk close from list"
            echo "  $0 info \"Google Chrome\"                - Get Chrome process information"
            echo "  $0 detect-hangs                         - Scan for and recover hung apps"
            ;;
    esac
    
    log_action "=== Process management operation completed ==="
}

# Execute main function
main "$@"

## Advanced Process Management Features

### Intelligent Hang Detection

```bash
#!/bin/bash

# Advanced hang detection with machine learning patterns
detect_application_patterns() {
    local process_name="$1"
    
    echo "=== Application Behavior Pattern Analysis ==="
    
    # Monitor CPU and memory usage over time
    local cpu_samples=()
    local memory_samples=()
    
    for i in {1..10}; do
        local pid
        pid=$(pgrep -f "$process_name" | head -1)
        
        if [[ -n "$pid" ]]; then
            local cpu_usage
            local mem_usage
            cpu_usage=$(ps -p "$pid" -o pcpu= | xargs)
            mem_usage=$(ps -p "$pid" -o pmem= | xargs)
            
            cpu_samples+=("$cpu_usage")
            memory_samples+=("$mem_usage")
        fi
        
        sleep 2
    done
    
    # Analyze patterns
    local avg_cpu=0
    local cpu_variance=0
    
    for cpu in "${cpu_samples[@]}"; do
        avg_cpu=$(echo "$avg_cpu + $cpu" | bc -l)
    done
    avg_cpu=$(echo "scale=2; $avg_cpu / ${#cpu_samples[@]}" | bc -l)
    
    echo "Average CPU Usage: ${avg_cpu}%"
    
    # Detect hang patterns
    if (( $(echo "$avg_cpu < 0.5" | bc -l) )); then
        echo "🚨 Pattern indicates potential hang: Very low CPU activity"
        return 1
    elif (( $(echo "$avg_cpu > 90" | bc -l) )); then
        echo "🚨 Pattern indicates potential infinite loop: Sustained high CPU"
        return 1
    else
        echo "✅ Process behavior appears normal"
        return 0
    fi
}

# Resource leak detection
detect_resource_leaks() {
    local process_name="$1"
    
    echo "=== Resource Leak Detection ==="
    
    local pid
    pid=$(pgrep -f "$process_name" | head -1)
    
    if [[ -z "$pid" ]]; then
        echo "Process not found: $process_name"
        return 1
    fi
    
    # Check memory growth
    local initial_memory
    initial_memory=$(ps -p "$pid" -o rss= | xargs)
    
    sleep 60  # Monitor for 1 minute
    
    local final_memory
    final_memory=$(ps -p "$pid" -o rss= | xargs)
    
    local memory_growth
    memory_growth=$((final_memory - initial_memory))
    
    echo "Memory Growth: ${memory_growth} KB in 60 seconds"
    
    if [[ $memory_growth -gt 50000 ]]; then  # More than 50MB growth
        echo "🚨 Potential memory leak detected"
        log_action "Memory leak detected in $process_name: ${memory_growth}KB growth"
        return 1
    fi
    
    # Check file descriptor leaks
    local open_files
    open_files=$(lsof -p "$pid" 2>/dev/null | wc -l)
    
    echo "Open File Descriptors: $open_files"
    
    if [[ $open_files -gt 1000 ]]; then
        echo "🚨 Potential file descriptor leak detected"
        log_action "File descriptor leak detected in $process_name: $open_files open files"
        return 1
    fi
    
    echo "✅ No resource leaks detected"
    return 0
}

## Important Configuration Notes

### macOS Process Control Commands

- **`killall`** - Terminate all processes by name (case-sensitive)
- **`kill`** - Terminate specific process by PID
- **`pkill`** - Pattern-based process termination
- **Signals** - TERM (graceful), KILL (immediate), ABRT (with core dump)

### Enterprise Integration Points

- **Security Information and Event Management (SIEM)** - Process termination logging
- **Application Performance Monitoring** - Integration with APM platforms
- **Incident Management Systems** - Automated ticket creation for hangs
- **Change Management** - Documentation of process interventions

### Best Practices for Enterprise Process Management

1. **Safety and Validation**
   - Always attempt graceful termination before force killing
   - Protect critical system processes from accidental termination
   - Implement business hours restrictions for productivity applications
   - Maintain comprehensive audit trails

2. **User Experience**
   - Attempt to save user work before terminating applications
   - Provide clear notifications about process terminations
   - Auto-restart critical applications when possible
   - Minimize disruption during business hours

3. **Security and Monitoring**
   - Detect and quarantine suspicious processes
   - Monitor for unusual resource consumption patterns
   - Implement hang detection and automatic recovery
   - Track process behavior for security analysis

4. **Troubleshooting and Diagnostics**
   - Collect detailed process information before termination
   - Generate crash reports for analysis
   - Monitor system performance impact
   - Provide comprehensive reporting capabilities

### Troubleshooting Common Issues

- **Process won't terminate** - Escalate through signal hierarchy (TERM → KILL)
- **System stability issues** - Avoid terminating critical system processes
- **Data loss concerns** - Implement work-saving procedures before termination
- **Resource leaks** - Monitor memory and file descriptor usage
- **Hang detection false positives** - Tune detection thresholds based on application behavior

Remember to test process management procedures thoroughly in a controlled environment before implementing across your entire MacFleet to ensure system stability and user productivity. 

Tutorial

Neue Updates und Verbesserungen zu Macfleet.

Konfiguration eines GitHub Actions Runners auf einem Mac Mini (Apple Silicon)

GitHub Actions Runner

GitHub Actions ist eine leistungsstarke CI/CD-Plattform, die es Ihnen ermöglicht, Ihre Software-Entwicklungsworkflows zu automatisieren. Während GitHub gehostete Runner anbietet, bieten selbst-gehostete Runner erhöhte Kontrolle und Anpassung für Ihr CI/CD-Setup. Dieses Tutorial führt Sie durch die Einrichtung, Konfiguration und Verbindung eines selbst-gehosteten Runners auf einem Mac mini zur Ausführung von macOS-Pipelines.

Voraussetzungen

Bevor Sie beginnen, stellen Sie sicher, dass Sie haben:

  • Einen Mac mini (registrieren Sie sich bei Macfleet)
  • Ein GitHub-Repository mit Administratorrechten
  • Einen installierten Paketmanager (vorzugsweise Homebrew)
  • Git auf Ihrem System installiert

Schritt 1: Ein dediziertes Benutzerkonto erstellen

Erstellen Sie zunächst ein dediziertes Benutzerkonto für den GitHub Actions Runner:

# Das 'gh-runner' Benutzerkonto erstellen
sudo dscl . -create /Users/gh-runner
sudo dscl . -create /Users/gh-runner UserShell /bin/bash
sudo dscl . -create /Users/gh-runner RealName "GitHub runner"
sudo dscl . -create /Users/gh-runner UniqueID "1001"
sudo dscl . -create /Users/gh-runner PrimaryGroupID 20
sudo dscl . -create /Users/gh-runner NFSHomeDirectory /Users/gh-runner

# Das Passwort für den Benutzer setzen
sudo dscl . -passwd /Users/gh-runner ihr_passwort

# 'gh-runner' zur 'admin'-Gruppe hinzufügen
sudo dscl . -append /Groups/admin GroupMembership gh-runner

Wechseln Sie zum neuen Benutzerkonto:

su gh-runner

Schritt 2: Erforderliche Software installieren

Installieren Sie Git und Rosetta 2 (wenn Sie Apple Silicon verwenden):

# Git installieren, falls noch nicht installiert
brew install git

# Rosetta 2 für Apple Silicon Macs installieren
softwareupdate --install-rosetta

Schritt 3: Den GitHub Actions Runner konfigurieren

  1. Gehen Sie zu Ihrem GitHub-Repository
  2. Navigieren Sie zu Einstellungen > Actions > Runners

GitHub Actions Runner

  1. Klicken Sie auf "New self-hosted runner" (https://github.com/<username>/<repository>/settings/actions/runners/new)
  2. Wählen Sie macOS als Runner-Image und ARM64 als Architektur
  3. Folgen Sie den bereitgestellten Befehlen, um den Runner herunterzuladen und zu konfigurieren

GitHub Actions Runner

Erstellen Sie eine .env-Datei im _work-Verzeichnis des Runners:

# _work/.env Datei
ImageOS=macos15
XCODE_15_DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer
  1. Führen Sie das run.sh-Skript in Ihrem Runner-Verzeichnis aus, um die Einrichtung abzuschließen.
  2. Überprüfen Sie, dass der Runner aktiv ist und auf Jobs im Terminal wartet, und überprüfen Sie die GitHub-Repository-Einstellungen für die Runner-Zuordnung und den Idle-Status.

GitHub Actions Runner

Schritt 4: Sudoers konfigurieren (Optional)

Wenn Ihre Actions Root-Privilegien benötigen, konfigurieren Sie die sudoers-Datei:

sudo visudo

Fügen Sie die folgende Zeile hinzu:

gh-runner ALL=(ALL) NOPASSWD: ALL

Schritt 5: Den Runner in Workflows verwenden

Konfigurieren Sie Ihren GitHub Actions Workflow, um den selbst-gehosteten Runner zu verwenden:

name: Beispiel-Workflow

on:
  workflow_dispatch:

jobs:
  build:
    runs-on: [self-hosted, macOS, ARM64]
    steps:
      - name: NodeJS installieren
        run: brew install node

Der Runner ist bei Ihrem Repository authentifiziert und mit self-hosted, macOS und ARM64 markiert. Verwenden Sie ihn in Ihren Workflows, indem Sie diese Labels im runs-on-Feld angeben:

runs-on: [self-hosted, macOS, ARM64]

Best Practices

  • Halten Sie Ihre Runner-Software auf dem neuesten Stand
  • Überwachen Sie regelmäßig Runner-Logs auf Probleme
  • Verwenden Sie spezifische Labels für verschiedene Runner-Typen
  • Implementieren Sie angemessene Sicherheitsmaßnahmen
  • Erwägen Sie die Verwendung mehrerer Runner für Lastverteilung

Fehlerbehebung

Häufige Probleme und Lösungen:

  1. Runner verbindet sich nicht:

    • Überprüfen Sie die Netzwerkverbindung
    • Überprüfen Sie die Gültigkeit des GitHub-Tokens
    • Stellen Sie angemessene Berechtigungen sicher
  2. Build-Fehler:

    • Überprüfen Sie die Xcode-Installation
    • Überprüfen Sie erforderliche Abhängigkeiten
    • Überprüfen Sie Workflow-Logs
  3. Berechtigungsprobleme:

    • Überprüfen Sie Benutzerberechtigungen
    • Überprüfen Sie sudoers-Konfiguration
    • Überprüfen Sie Dateisystem-Berechtigungen

Fazit

Sie haben jetzt einen selbst-gehosteten GitHub Actions Runner auf Ihrem Mac mini konfiguriert. Diese Einrichtung bietet Ihnen mehr Kontrolle über Ihre CI/CD-Umgebung und ermöglicht es Ihnen, macOS-spezifische Workflows effizient auszuführen.

Denken Sie daran, Ihren Runner regelmäßig zu warten und ihn mit den neuesten Sicherheitspatches und Software-Versionen auf dem neuesten Stand zu halten.

Native App

Macfleet native App

Macfleet Installationsanleitung

Macfleet ist eine leistungsstarke Flottenmanagement-Lösung, die speziell für Cloud-gehostete Mac Mini-Umgebungen entwickelt wurde. Als Mac Mini Cloud-Hosting-Anbieter können Sie Macfleet verwenden, um Ihre gesamte Flotte virtualisierter Mac-Instanzen zu überwachen, zu verwalten und zu optimieren.

Diese Installationsanleitung führt Sie durch die Einrichtung der Macfleet-Überwachung auf macOS-, Windows- und Linux-Systemen, um eine umfassende Übersicht über Ihre Cloud-Infrastruktur zu gewährleisten.

🍎 macOS

  • Laden Sie die .dmg-Datei für Mac hier herunter
  • Doppelklicken Sie auf die heruntergeladene .dmg-Datei
  • Ziehen Sie die Macfleet-App in den Anwendungsordner
  • Werfen Sie die .dmg-Datei aus
  • Öffnen Sie Systemeinstellungen > Sicherheit & Datenschutz
    • Datenschutz-Tab > Bedienungshilfen
    • Aktivieren Sie Macfleet, um Überwachung zu erlauben
  • Starten Sie Macfleet aus den Anwendungen
  • Die Verfolgung startet automatisch

🪟 Windows

  • Laden Sie die .exe-Datei für Windows hier herunter
  • Rechtsklick auf die .exe-Datei > "Als Administrator ausführen"
  • Folgen Sie dem Installationsassistenten
  • Akzeptieren Sie die Allgemeinen Geschäftsbedingungen
  • Erlauben Sie in Windows Defender, wenn aufgefordert
  • Gewähren Sie Anwendungsüberwachungsberechtigungen
  • Starten Sie Macfleet aus dem Startmenü
  • Die Anwendung beginnt automatisch mit der Verfolgung

🐧 Linux

  • Laden Sie das .deb-Paket (Ubuntu/Debian) oder .rpm (CentOS/RHEL) hier herunter
  • Installieren Sie mit Ihrem Paketmanager
    • Ubuntu/Debian: sudo dpkg -i Macfleet-linux.deb
    • CentOS/RHEL: sudo rpm -ivh Macfleet-linux.rpm
  • Erlauben Sie X11-Zugriffsberechtigungen, wenn aufgefordert
  • Fügen Sie den Benutzer zu entsprechenden Gruppen hinzu, falls erforderlich
  • Starten Sie Macfleet aus dem Anwendungsmenü
  • Die Anwendung beginnt automatisch mit der Verfolgung

Hinweis: Nach der Installation auf allen Systemen melden Sie sich mit Ihren Macfleet-Anmeldedaten an, um Daten mit Ihrem Dashboard zu synchronisieren.