Process.start în Dart

Pornește un program și returnează imediat un obiect Process, prin care îi trimiți date și îi citești ieșirea în timp ce rulează.

Sintaxă
static Future<Process> start(String executable, List<String> arguments,
    {String? workingDirectory, Map<String, String>? environment,
     bool runInShell = false, ProcessStartMode mode = ProcessStartMode.normal})

IOSink get stdin
Stream<List<int>> get stdout
Stream<List<int>> get stderr
Future<int> get exitCode

Ce face Process.start

Spre deosebire de Process.run, care așteaptă finalul, Process.start returnează un obiect Process imediat după pornire. Prin el comunici cu programul cât timp rulează.

process.stdin este un IOSink în care scrii datele trimise programului; îl închizi cu await process.stdin.close() ca programul să afle că nu mai vin date. process.stdout și process.stderr sunt fluxuri de octeți; le decodifici cu utf8.decoder și le împarți în rânduri cu LineSplitter.

process.exitCode este un Future<int> care se completează când programul se termină. Citește (sau golește) întotdeauna stdout și stderr: dacă nimeni nu le citește, programul se poate bloca atunci când bufferul se umple.

Parametri

Parametru Descriere
executable Programul de pornit.
arguments Lista argumentelor.
mode Opțional. ProcessStartMode.inheritStdio leagă ieșirile programului direct de terminalul tău; detached îl lasă să ruleze după ce programul Dart se termină.

Ce returnează

Un Future<Process> cu stdin, stdout, stderr, exitCode, pid și kill.

Exemple

Exemplul 1: Date trimise lui sort și rezultatul citit

import 'dart:convert';
import 'dart:io';

Future<void> main() async {
  final proces = await Process.start('sort', []);
  for (final oras in ['Timișoara', 'Arad', 'Iași', 'Brașov']) {
    proces.stdin.writeln(oras);
  }
  await proces.stdin.close();

  final sortate = await proces.stdout.transform(utf8.decoder).transform(const LineSplitter()).toList();
  print(sortate);
  print('Cod de ieșire: ${await proces.exitCode}');
}

Rezultat

[Arad, Brașov, Iași, Timișoara]
Cod de ieșire: 0

Exemplul 2: Ieșirea citită rând cu rând, pe măsură ce apare

import 'dart:convert';
import 'dart:io';

Future<void> main() async {
  final proces = await Process.start('sh', ['-c', r'for pas in 1 2 3; do echo "Pasul $pas gata"; done']);
  await proces.stdout
      .transform(utf8.decoder)
      .transform(const LineSplitter())
      .forEach((rand) => print('[copil] $rand'));
  print('Terminat cu codul ${await proces.exitCode}');
}

Rezultat

[copil] Pasul 1 gata
[copil] Pasul 2 gata
[copil] Pasul 3 gata
Terminat cu codul 0

Exemplul 3: stdout și stderr citite în același timp

import 'dart:convert';
import 'dart:io';

Future<void> main() async {
  final proces = await Process.start('sh', ['-c', 'echo "copiez fișierele"; echo "lipsește poza.jpg" >&2; exit 2']);
  final iesire = proces.stdout.transform(utf8.decoder).join();
  final erori = proces.stderr.transform(utf8.decoder).join();
  final cod = await proces.exitCode;
  print('Ieșire: ${(await iesire).trim()}');
  print('Erori: ${(await erori).trim()}');
  print('Cod: $cod');
}

Rezultat

Ieșire: copiez fișierele
Erori: lipsește poza.jpg
Cod: 2

Greșeli frecvente

  • Uiți await proces.stdin.close(): programe ca sort așteaptă la nesfârșit restul datelor, iar exitCode nu se mai completează.
  • Aștepți exitCode fără să citești stdout: când programul scrie mult, bufferul se umple, programul se oprește și așteaptă, iar al tău așteaptă după el.

Comenzi înrudite

  • Process.run: Pornește alt program, așteaptă să se termine și returnează ce a scris (stdout, stderr) și codul de ieșire.
  • Process.kill: kill trimite un semnal de oprire unui proces pornit cu Process.start; pid este numărul procesului dat de sistem.
  • ProcessResult: Rezultatul lui Process.run: codul de ieșire și tot ce a scris programul în stdout și în stderr.
  • LineSplitter: Împarte un text în rânduri, recunoscând \n, \r\n și \r; funcționează și pe fluxuri cu transform.
  • IOSink: Destinația în care scrii text sau octeți: un fișier deschis (openWrite), stdout, stderr sau răspunsul HTTP.