Philipp
Philipp

Reputation: 11361

Start server in background, run code and stop server again in single script

I want to create a bash script that starts a server, waits for the server to be started, then runs some code (which us handled by the server) and finally stops the server again.

Here's what I've got, with remarks on why it's not working:

#!/bin/bash

# Expected: Start the local selenium server and push it to the background.
# Actual: Script continues instantly without waiting for the server to start!
selenium-server -port 4444 &

# Expected: Run the tests, which require the local selenium server to be started
# Actual: Tests fail because the server is not ready.
phpunit tests/ui-tests.php

# Expected: Exiting the process also stops the background job (server).
# Actual: The server continues running interactively in the terminal until stopped via Ctrl-C.
exit

What's the correct (or better) approach for this kind of script?

Upvotes: 1

Views: 1233

Answers (2)

Lane Henslee
Lane Henslee

Reputation: 51

I have a function called dev that starts my server in the background, then waits, that way I can use a trap dev_term INT to clean up everything with ctrl-c. Usually I have a frontend server and a backend server running in the background so I'm excited to apply this to that.

function dev_term() {
    kb
    docker compose -f dev-compose.yml down
}

function dev () {
    local start=$(pwd)
    gotoroot
    trap dev_term INT
    docker compose -f dev-compose.yml up -d
    cd backend && python manage.py runserver &
    backend_pid=$!
    wait
}

function kb () {
    kill $backend_pid 2>/dev/null
}

Upvotes: 0

Philipp
Philipp

Reputation: 11361

Here's the working script which I built based on the feedback of markp-fuso:

#!/bin/bash

start_server() {
    echo "Start server ..."
    selenium-server -port 4444 &
    server_pid=$!

    # Wait for the server to start (max 10 seconds)
    for attempt in {1..10}; do
        my_pid=$(lsof -t -i tcp:4444)

        if [[ -n $my_pid ]]; then
            # Make sure the running server is the one we just started.
            if [[ $my_pid -ne $server_pid ]]; then
                echo "ERROR: Multiple Selenium Servers running."
                echo "→ lsof -t -i tcp:4444 | xargs kill"
                exit 1
            fi

            break
        fi

        sleep 1
    done

    if [[ -z $my_pid ]]; then
        echo "ERROR: Timeout while waiting for Selenium Server"
        exit 1
    fi
}

stop_server() {
    echo "Stop Server ..."
    kill $server_pid
}

# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 

start_server

phpunit tests/ui-tests.php

stop_server

Upvotes: 2

Related Questions