startShellJob method
Future<Result<ShellJob, ExecutionError> >
startShellJob(
- String command, {
- required String id,
- required String logPath,
- ShellExecOptions? options,
override
Starts command detached: stdout/stderr append to logPath and the
returned ShellJob keeps running until it exits or is stopped.
ShellExecOptions.timeout and ShellExecOptions.cancelToken still
apply (both stop the job).
Implementation
@override
Future<Result<ShellJob, ExecutionError>> startShellJob(
String command, {
required String id,
required String logPath,
ShellExecOptions? options,
}) async {
final token = options?.cancelToken;
if (token?.isCancelled ?? false) {
return const Err(ExecutionError(ExecutionErrorCode.aborted, 'aborted'));
}
final started = await _start(command, options);
if (started.isErr) return Err(started.errorOrNull!);
final process = started.valueOrNull!;
// Feed optional stdin data (bash tool `stdin` param), then close the
// pipe — background jobs are not interactive beyond this.
if (options?.stdinData != null) {
try {
process.stdin.write(options!.stdinData);
await process.stdin.flush();
} on Object {
// Process already gone — the settle path reports the real status.
}
}
unawaited(process.stdin.close());
final IOSink logSink;
try {
logSink = File(logPath).openWrite(mode: FileMode.append);
} on Object catch (error) {
process.kill();
return Err(
ExecutionError(
ExecutionErrorCode.spawnError,
'cannot open job log file $logPath: $error',
cause: error,
),
);
}
return Ok(
_LocalShellJob(
id: id,
command: command,
logPath: logPath,
process: process,
logSink: logSink,
timeout: options?.timeout,
token: token,
),
);
}