Around Go: command line · 3 MIN READ
Processes, signals and exit status
Start one Go service, retain its PID, send TERM and wait for its result.
A process has a PID, an exit status and open streams. Starting a service in the background does not detach it from responsibility: keep the PID and wait for completion. These commands assume a local Go project with cmd/api and an available port.
Start the binary you can stop directly
Build first, then run the binary itself in the background. $! is the PID of the latest asynchronous command. A background go run process may introduce a build/launcher process, so it is a poor substitute when practicing exact signal ownership.
mkdir -p bin
go build -o ./bin/api ./cmd/api
./bin/api > api.log 2>&1 &
api_pid=$!
printf "API PID: %s\n" "$api_pid"Run the launch only after the build succeeds. Both output streams go to api.log. Record this PID instead of searching all processes by a broad application name or terminating unrelated Go jobs.
Inspect the process and the listening port
ps reports process state; kill -0 checks that a PID can be addressed without sending a signal. lsof is a separately installed utility on some systems and can identify a listening socket; it does not prove the HTTP handler returns useful responses.
ps -p "$api_pid" -o pid,etime,args
kill -0 "$api_pid"
lsof -nP -iTCP:8080 -sTCP:LISTENCheck that the socket belongs to the binary you launched. If lsof is missing, use your OS socket inspection tool. A process may exit between any two commands; observation is not a lifetime guarantee.
Request shutdown and collect the outcome
TERM lets a cooperative service drain work. wait observes your shell child and reaps it; an if branch can preserve nonzero status without aborting the shell. SIGKILL prevents application cleanup, so use it only after diagnosing an unresponsive process.
kill -TERM "$api_pid"
if wait "$api_pid"; then
printf "%s\n" "Service exited successfully"
else
status=$?
printf "Service exit status: %s\n" "$status"
fi
tail -n 20 api.logA graceful service can return zero. A process terminated by a signal may report a nonzero status; inspect its log and shutdown contract. wait works for children of this shell, not any arbitrary PID from another terminal.
TAKE THIS WITH YOU
Keep the child PID, inspect it, request TERM and wait for the outcome. A listening port, a live process and a successful HTTP response are three different observations.
Check your understanding
What does wait "$api_pid" do for a child started in this shell?
Go to the source
Progress stays in this browser. No account needed.