Control

Read a background command

What a backgrounded command has printed since you last asked, and whether it is still running.

The read is CONSUMING and the cursor is the daemon’s, not yours: each call returns what has arrived since the previous call and advances the handle’s offset itself. There is nothing to pass — the stdout_offset and stderr_offset on the response are how far it has now read, reported so you can tell how much has gone by, not a parameter to send back. Output you receive and drop is gone.

stdout_b64 and stderr_b64 are base64 and always are; the offsets count the DECODED bytes, which is what makes them line up across polls.

more is the field to poll on: it says there is further output waiting right now.

A handle answers 404 from ten minutes after its command exits, and after the daemon on the computer’s host restarts — the same 404 as a pid that never existed. A stopped or suspended computer answers 409 with reason: "unavailable", and this route does not resume it. A suspended one still holds the command: after a resume, its output and exit code can be read again.

Only commands this API started can be read this way.

Requires the member role or higher.

get/computers/{id}/exec/{pid}

Request

  • Base URL: https://app.mandala.computer/api/v1
  • URL: https://app.mandala.computer/api/v1/computers/{id}/exec/{pid}
  • Auth: HTTP bearer

Path parameters

idstring required

The computer id.

pidstring required

The guest pid from a backgrounded exec.

Response

Its state and whatever it has printed since the last read.

execution_idstring required

The stable ID originally returned by background exec.

pidinteger required
commandstring required

The command line, echoed back.

runningboolean required
exitedboolean required
exit_codeinteger

Absent until it has exited — absent rather than 0, which is the one value worth trusting.

stdout_b64string required

What it has printed since your previous read, base64. This read consumes it.

Always base64, on every response, for the reason Exec gives — and here there is a second one. A poll stops at a 1 MiB ceiling, and that cut lands on a byte offset: a multi-byte character sitting across it would have had BOTH of its halves replaced. Ordinary text output was being corrupted at every megabyte, not only binary output. Decoded, the two halves join back into the character they came from.

stderr_b64string required
stdout_offsetinteger required

How far the daemon has now read. Reported, not a parameter — see the note above.

stderr_offsetinteger required
moreboolean

There is further output waiting right now. This is the flag to poll on.

ABSENT rather than false when there is not, so false is a value this field never carries: code waiting for more === false waits for ever. Polling is safe either way — !more reads the same for absent and false — and no schema here marks it required, so an ordinary client simply sees undefined. What it is not safe to do is declare it a required boolean and put a strict runtime validator behind that, which rejects the ordinary response rather than the unusual one.

killedboolean

A DELETE /computers/{id}/exec/{pid} reached this command while the platform still had it running. Absent rather than false otherwise, on the same terms as more.

That is weaker than “it did not finish on its own”, and the difference is a real one rather than a caution. Whether a command has exited is noticed by a poll, so a command that ended a moment before your DELETE arrived is still running as far as this platform knows: the stop is carried out against a process group that has already gone, which succeeds, and the flag is set. So killed tells you what YOU did, not how the command ended. exit_code is what says that, and a command stopped by a signal reports the code its shell gives for one.

started_atstring required

RFC 3339 timestamp.

Changes

No recorded changes to this operation across all 1 revision of this API.