Support capturing stdout/stderr in memory with nob_cmd_run / nob_cmd_run_opt
Hi!
I’m using Nob to run commands and capture their output directly in memory (as a char* string). With the older functions (nob_cmd_run_async_redirect), this was straightforward using pipes.
char *run_cmd_and_get_output(Nob_Cmd *cmd) {
int pipefd[2];
if (pipe(pipefd) == -1) {
perror("pipe");
return NULL;
}
Nob_Cmd_Redirect cmd_red = {0};
cmd_red.fdout = &pipefd[1];
nob_cmd_run_async_redirect(*cmd, cmd_red);
cmd->count = 0;
close(pipefd[1]);
char *buffer = NULL;
size_t total_size = 0;
char tmp_buffer[256];
ssize_t bytes_read;
while ((bytes_read = read(pipefd[0], tmp_buffer, sizeof(tmp_buffer))) > 0) {
char *new_buffer = realloc(buffer, total_size + bytes_read + 1);
if (!new_buffer) {
free(buffer);
close(pipefd[0]);
return NULL;
}
buffer = new_buffer;
memcpy(buffer + total_size, tmp_buffer, bytes_read);
total_size += bytes_read;
}
if (buffer) {
buffer[total_size] = '\0';
}
close(pipefd[0]);
return buffer;
}
In the new API (nob_cmd_run / nob_cmd_run_opt):
- cmd->count is always reset (understood and not an issue).
- There is currently no simple official way to capture stdout/stderr in memory without requiring saving to a file and then reading it afterwards.
It would be very useful if Nob provided a first-class, easy way to run a command asynchronously and capture stdout/stderr directly in memory, without the need for file hacks. I could also use the new stdout option to nob_cmd_run_opt and then read that file. However I dont find it as clean, I think it is cleaner to not save to a file just to then read the same file.
This would make migrating from the old API much smoother for me.
Thank you!
It was already implemented on one of the streams, bet not published yet. yt