geth/docs/automation-examples.md

3.6 KiB

Automation Examples

These examples are intended as starting points for local scripts and infrastructure automation. They assume the single geth executable is on PATH.

Use --json when one process invocation produces one result that will be parsed as a complete document. Use --jsonl for line-oriented shell pipelines: each current command writes one compact object on one physical line. The flags are mutually exclusive, and failures use the same type: "error" envelope and return a nonzero exit status in either mode.

Shell

Initialize a home, start the daemon in a user-owned process, wait for control, and read stable JSON status:

#!/usr/bin/env sh
set -eu

export GETH_HOME="${GETH_HOME:-$HOME/.local/share/geth/geth}"

geth init
geth daemon run >"$GETH_HOME/daemon.log" 2>&1 &
daemon_pid=$!
trap 'kill "$daemon_pid" 2>/dev/null || true' EXIT

geth wait daemon --timeout-ms 30000
geth doctor --json
geth status --json

For a compact line suitable for an append-only log or jq -c pipeline:

geth status --jsonl >>geth-status.jsonl
tail -n 1 geth-status.jsonl | jq -r '.type'

Create a backup into a separate directory and validate that it can restore to a new home:

#!/usr/bin/env sh
set -eu

backup_dir="${1:?backup dir required}"
restore_home="$(mktemp -d)"

geth backup create --out "$backup_dir"
geth backup restore "$backup_dir" --target-home "$restore_home"
GETH_HOME="$restore_home" geth doctor --json || true

Python JSON

Use CLI JSON output without parsing human text:

#!/usr/bin/env python3
import json
import os
import subprocess
import sys


def geth(*args, check=True):
    proc = subprocess.run(
        ["geth", "--json", *args],
        check=False,
        text=True,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        env=os.environ.copy(),
    )
    if check and proc.returncode != 0:
        raise RuntimeError(proc.stderr or proc.stdout)
    return json.loads(proc.stdout)


doctor = geth("doctor", check=False)
for check in doctor["checks"]:
    print(check["status"], check["code"], check["message"])

status = geth("status")
print(status["node_id"], status.get("endpoint_id"))

Wait for a known peer before pulling sync status:

#!/usr/bin/env python3
import json
import subprocess
import sys

node = sys.argv[1]

wait = subprocess.run(
    ["geth", "--json", "wait", "peer", node, "--timeout-ms", "30000"],
    text=True,
    stdout=subprocess.PIPE,
)
report = json.loads(wait.stdout)
if not report["ready"]:
    raise SystemExit(report["reason"])

sync = subprocess.check_output(["geth", "--json", "sync", "status"], text=True)
print(sync)

User Service

Install and operate the daemon through the current user's service manager. These commands do not install a system service and do not require privileged service manager mutation:

geth daemon service print
geth daemon install
geth wait daemon --timeout-ms 30000
geth daemon status
geth daemon stop
geth daemon uninstall

For a disposable interactive test, geth daemon run --ephemeral creates and prints a temporary home. Other commands can target it explicitly with geth --home <printed-path> ...; normal Ctrl-C shutdown removes the state.

Admin SSH keys remain outside geth state. Automation should pass public admin keys with --admin-key and use the matching private key only as an argument to the explicit signing command when an admin operation is intended:

geth init \
  --admin-key "$HOME/.ssh/id_ed25519.pub" \
  --signing-key "$HOME/.ssh/id_ed25519" \
  --node-name "$(hostname)"

Do not copy private SSH admin keys into GETH_HOME, backups, service definitions, or shared project repositories.