captureLoginPath function
Runs shell as a login+interactive shell and returns the PATH it exports,
or null on Windows, when script/the shell fails, on timeout, or when the
markers are missing.
Implementation
Future<String?> captureLoginPath({
required String shell,
Duration timeout = const Duration(seconds: 10),
}) async {
if (Platform.isWindows) return null;
Process process;
try {
process = await Process.start(shell, [
'-l',
'-i',
'-c',
'printf "$_startMarker%s$_endMarker" "\$PATH"',
], runInShell: false);
} on Object {
return null;
}
final stdoutFuture = process.stdout.transform(utf8.decoder).join();
// Drain stderr so the child does not block on a full pipe.
unawaited(process.stderr.drain<void>());
Timer? killer;
killer = Timer(timeout, () => process.kill(ProcessSignal.sigkill));
try {
final exitCode = await process.exitCode;
final out = await stdoutFuture;
killer.cancel();
if (exitCode != 0 && !out.contains(_startMarker)) return null;
return _extract(out);
} on Object {
killer.cancel();
return null;
}
}