I'm working on a Bash function and need to capture the stderr stream to a variable 'e' while executing some logic. The command looks something like this: `r="0"; e=""; m="$(eval "$logic")" || r="1" && returnCode="1"`. I'm trying to avoid writing to a temporary file to store the output. Is there a way to achieve this without using a temp file?
4 Answers
Consider this approach: `r="0"; e=""; m="$(eval "$logic" 2> >(e=$(cat)))" || r="1" && returnCode="1"`. Also, using file descriptor manipulation with `exec` can help separate streams without cluttering your structure too much. Just be careful with subshells because they can complicate variable scope.
So you're saying it's a matter of scope? I thought the build-up there would keep things intact. Thanks for the insight!
I get wanting to avoid temp files, but they often simplify the process of capturing output reliably. Until a better redirection method is standard, many of us rely on them to manage output streams effectively. What’s your concern with using them at scale?
Yeah, temp files are fine for one-off cases, but when running multiple commands, it leads to unnecessary I/O overhead. Also, managing cleanup can get tricky if not handled properly!
As of now, you might have to use a temp file or merge the stdout and stderr streams into a single variable but still find a way to separate them later. For example, you could use a combination of process substitution and `mapfile` to read both streams into separate arrays. Once Bash 5.3 is released, you'll have more options with the new braces syntax that allows direct assignment of stderr to variables without temp files. It's definitely something to keep an eye on!
Wait, you can do that with `${ }` in Bash? Mind-blown!
Sounds like a good plan, I guess temp files are just a trade-off for simplicity. Thanks for the advice!
Keep in mind that unbuffered stderr can sometimes mix in with buffered stdout. This usually doesn't create issues, but it's something to watch out for if you're depending on sequence in your output.
True! Buffering can throw a wrench in things; I've faced issues before. But there are typically ways to work around it!
I tried your method, but I think it’s being executed in a subshell context, which is causing it not to work properly.