Search code examples
bashdialogtee

Bash - redirect command to dialog and var with tee


How can I display the output of a command (including stderr) with dialog programbox in real-time and also capture the piped input in a var?

So far, I could only achieve either one of these goals.

As pointed out here, tee /dev/tty should work, but the ongoing piping and stdout redirection for dialog's output seems to prevent successful capturing in the following example.

Instead, the output will get printed in the terminal (as /dev/tty usually does). What do I need to change, to make it work?

#! /bin/bash
exec 3>&1
output=$(git worktree remove -- "mytestbranch" 2>&1 | tee /dev/tty | dialog --colors --no-collapse --programbox 20 120 1>&3)
exec 3>&-
echo -e "OUTPUT: ${cmdOutput[@]}"

I've seen other approaches with tee, which redirect directly into a command, similar to this:

cmdOutput=$(git worktree remove -- "mytestbranch" 2>&1 | tee >(dialog --colors --no-collapse --programbox 20 120 1>&3) | cat)

That way, I could actually get the output to dialog AND the var, but afterwards, the tty output seems to be messed-up, i. e., keyboard input isn't displayed anymore in the terminal, at least in cygwin - the commands typed are still parsed and their output is displayed, though.

A closer observation reveals, that the script, from which the command is run, seems to return early (without programbox waiting for the OK keypress); the first time pressing ENTER after running it makes the cursor disappear, the second time makes it re-appearing several lines above in the terminal.

When re-selecting the last command from the history in this state instead, the error -bash: OA: command not found is displayed.

What might be the cause and how to prevent the misbehavior?


Solution

  • Use process substitutions like so:

    var=$({ git ... 2>&1 | tee >(cat >&3) | dialog ... >/dev/tty;} 3>&1)