dartssh2
dartssh2 copied to clipboard
Output of remote "tail - f"
Can someone please provide an example of gathering a continuous stream of string lines from a remotely executed "tail - f"?
Hi, thanks for your interest in this package! To spawn a process and listen to its output, simply use SSHClient.execute
as follows:
final client = SSHClient(...);
final session = await client.execute('tail -f path/to/file');
await for (final chunk in session.stdout.cast<List<int>>().transform(Utf8Decoder())) {
print('got: $chunk');
}
Thanks a lot @xtyxtyx for the reply!
I made the following solution that worked for me, just wasn't sure if it was the best possible one. I have "misused" the fact that stdout returns buffered list of characters, containing at least one whole line, or more.
List<String> outputLines = [];
Future<SSHClient> connect() async {
return SSHClient(
await SSHSocket.connect(host!, port!),
username: username!,
onPasswordRequest: () => password!,
);
}
Stream<Uint8List> tailf() async* {
final connection = await connect();
final client = await connection.execute('tail -f /var/log/some.log');
yield* client.stdout;
}
void output() {
tailf().listen((event) {
final output = utf8.decode(event);
const lineSplitter = LineSplitter();
final lineBuffer = lineSplitter.convert(output);
for (var x = 0; x < lineBuffer.length; x++) {
outputLines.add(lineBuffer[x]);
log('New line: ${lineBuffer[x]}');
// Here goes the code where the output can be added to a state management solution of choice
}
});
}
In case the output is slower and buffer contains less than a full line, I'd have to listen to stderr output, I guess, as it sends each character separately, then populate the lineBuffer until the received character is new line (RegExp(r'\n')) and then add it to outputLines...
Anyway, kudos for the work on this package, I've picked it specifically as it's a pure Dart implementation and, therefore, it's the easiest for cross-platform migration.
Edit: forgot to add: your solution is much more elegant!