ProcessResult în Dart

Rezultatul lui Process.run: codul de ieșire și tot ce a scris programul în stdout și în stderr.

Sintaxă
class ProcessResult {
  final int exitCode;
  final dynamic stdout;   // String sau List<int>
  final dynamic stderr;   // String sau List<int>
  final int pid;
}

Ce face ProcessResult

ProcessResult este obiectul returnat de Process.run și Process.runSync. exitCode este codul cu care s-a terminat programul: 0 înseamnă succes, orice altă valoare înseamnă eroare (fiecare program își alege codurile).

stdout și stderr conțin tot textul scris de program pe cele două ieșiri. Tipul lor este dynamic: implicit sunt String, decodificate cu codificarea sistemului; dacă dai stdoutEncoding: null (sau stderrEncoding: null), primești octeții ca List<int>. De aceea le convertești cu as String înainte de a apela metode de text.

pid este numărul procesului care a rulat; procesul s-a terminat deja când primești rezultatul.

Exemple

Exemplul 1: Cele trei câmpuri principale

Comanda scrie un rând în stdout, unul în stderr și se termină cu codul 3.

import 'dart:io';

void main() {
  final r = Process.runSync('sh', ['-c', 'echo "Raport gata"; echo "Lipsește nota lui Ion" >&2; exit 3']);
  print('exitCode: ${r.exitCode}');
  print('stdout: ${(r.stdout as String).trim()}');
  print('stderr: ${(r.stderr as String).trim()}');
  print('Succes: ${r.exitCode == 0}');
}

Rezultat

exitCode: 3
stdout: Raport gata
stderr: Lipsește nota lui Ion
Succes: false

Exemplul 2: O funcție care verifică rezultatul

import 'dart:io';

String ruleaza(String program, List<String> argumente) {
  final r = Process.runSync(program, argumente);
  if (r.exitCode != 0) {
    return 'EȘEC (${r.exitCode}): ${(r.stderr as String).trim()}';
  }
  return (r.stdout as String).trim();
}

void main() {
  File('orase.txt').writeAsStringSync('Iași\nCluj\nBrașov\n');
  print(ruleaza('grep', ['Cluj', 'orase.txt']));
  print(ruleaza('sh', ['-c', 'echo "fișier inexistent" >&2; exit 1']));
}

Rezultat

Cluj
EȘEC (1): fișier inexistent

Exemplul 3: Octeți în loc de text

Cu stdoutEncoding: null, stdout este o listă de octeți; „ș” ocupă doi octeți în UTF-8.

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

void main() {
  final r = Process.runSync('printf', ['Iași'], stdoutEncoding: null);
  final octeti = r.stdout as List<int>;
  print('Octeți: $octeti');
  print('Text: ${utf8.decode(octeti)}');
}

Rezultat

Octeți: [73, 97, 200, 153, 105]
Text: Iași

Greșeli frecvente

  • Scrii r.stdout.trim() fără as String: tipul este dynamic, iar dacă ai cerut octeți programul cade la rulare. Convertește explicit.
  • Cauți mesajul de eroare în stdout: majoritatea programelor scriu erorile în stderr.

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.start: 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ă.
  • stderr: stderr este ieșirea de erori a programului, separată de stdout; aici scrii avertismentele și mesajele de eroare.
  • utf8: Codec-ul UTF-8: encode transformă textul în octeți, decode transformă octeții înapoi în text.