#!/bin/bash PID_FILE="server.pid" # --- Find Go Executable --- GO_EXECUTABLE="" echo "Attempting to locate Go executable..." # Prioritize standard manual install location if [[ -x "/usr/local/go/bin/go" ]]; then GO_EXECUTABLE="/usr/local/go/bin/go" echo "Found Go executable at: $GO_EXECUTABLE (standard location)" else # Fallback: Check if 'go' is somehow in the current (sudo) PATH echo "Go not found in /usr/local/go/bin. Checking PATH..." if command -v go &> /dev/null; then # Verify the result of command -v is executable potential_go=$(command -v go) if [[ -x "$potential_go" ]]; then GO_EXECUTABLE="$potential_go" echo "Found Go executable in PATH at: $GO_EXECUTABLE" else echo "Found 'go' via command -v, but '$potential_go' is not executable." fi else echo "'go' command not found in PATH either." fi fi # Check if we found a valid executable if [[ -z "$GO_EXECUTABLE" ]]; then echo "Error: Could not find a usable 'go' executable." >&2 # Error to stderr echo "Checked /usr/local/go/bin/go and the PATH available to sudo." >&2 echo "Ensure Go is installed correctly and accessible." >&2 exit 1 fi # --- End Find Go Executable --- # --- Kill existing process --- if [ -f "$PID_FILE" ]; then PID=$(cat "$PID_FILE") if [[ "$PID" =~ ^[0-9]+$ ]]; then echo "Attempting to kill process with PID: $PID" # Check if process exists before trying to kill if kill -0 "$PID" 2>/dev/null; then kill "$PID" sleep 0.5 # Give it a moment to shut down # Verify kill (optional but good practice) if kill -0 "$PID" 2>/dev/null; then echo "Warning: Failed to kill process $PID. Trying kill -9..." kill -9 "$PID" sleep 0.5 fi # Final check after kill attempts if ! kill -0 "$PID" 2>/dev/null; then echo "Process $PID killed." else echo "Error: Could not kill process $PID even with -9." >&2 # Consider exiting if kill fails critically # exit 1 fi else echo "Process with PID $PID does not seem to be running." fi else echo "Invalid PID '$PID' found in $PID_FILE. Removing stale file." rm -f "$PID_FILE" # Use -f to avoid error if file gone fi else echo "PID file '$PID_FILE' not found. Assuming server is not running." fi # --- Start the server (foreground, let app daemonize) --- echo "Restarting server using: $GO_EXECUTABLE" # Show which executable is used # Run the command, capture its output (stdout & stderr) OUTPUT_CAPTURE=$(mktemp) # Ensure temp file is cleaned up on exit (normal or error) trap 'echo "Cleaning up temp file: $OUTPUT_CAPTURE"; rm -f -- "$OUTPUT_CAPTURE"' EXIT # Execute the command, redirecting stdout and stderr to the temp file # We also use 'tee' so the user sees the output in real-time # Use 'if ! ...; then ... fi' structure for clarity on failure if ! "$GO_EXECUTABLE" run main.go -p -b 2>&1 | tee "$OUTPUT_CAPTURE"; then # This block executes if 'go run' exits with an error (non-zero status) # This might happen if there's a compile error or immediate crash before daemonizing echo "Error: '$GO_EXECUTABLE run' command failed with exit status $?. See output above and in $OUTPUT_CAPTURE" >&2 # Optionally 'cat $OUTPUT_CAPTURE' here if tee might not have flushed exit 1 fi # If the command succeeded (exit status 0), continue echo "Go command finished (expected if daemonizing)." # --- Extract PID from the application's captured output --- # Look for the specific line the app prints using grep and extract the number # -oP uses Perl-compatible regexes for lookbehind \K to get only the number NEW_PID=$(grep -oP 'Server started in daemon mode with PID: \K[0-9]+' "$OUTPUT_CAPTURE") # --- Verify and save PID --- if [[ "$NEW_PID" =~ ^[0-9]+$ ]]; then # Double-check if the extracted PID actually exists as a process # Add a small delay in case the process needs a moment to stabilize after logging sleep 0.2 if kill -0 "$NEW_PID" 2>/dev/null; then echo "Server successfully started and daemonized with PID: $NEW_PID" echo "$NEW_PID" > "$PID_FILE" echo "PID saved to $PID_FILE." else # This is a potential race condition or the app failed right after logging PID echo "Error: Extracted PID $NEW_PID from logs, but process $NEW_PID is not running." >&2 echo "The application might have failed immediately after starting." >&2 echo "Check full output in $OUTPUT_CAPTURE" >&2 # exit 1 # Decide if this is a fatal error fi else echo "Error: Could not extract PID from server output in $OUTPUT_CAPTURE." >&2 echo "Expected a line like 'Server started in daemon mode with PID: XXXX'" >&2 # exit 1 # Decide if this is a fatal error fi # Cleanup happens automatically via trap echo "Restart script finished."