2

I'm running rman commands from Bash scripts. I pass my commands to rman using here documents. I want to capture the output but also at the same time print it to the console (real-time). I found this solution, but I don't how to make it to work with here-docs.

VAR=$(ls | tee /dev/tty)

What I currently run is:

output=$(rman <<RMAN
$rman_script
RMAN
)

Do you know how in this RMAN example I could also print stdout to the console apart from storing it in the output variable? Any help is appreciated. Cheers.

damian
  • 316
  • 3
  • 7
  • 23
  • 1
    This looks like a poor fit for a Bash script. Maybe some of the ugliness could be refactored with `output=$(echo "$rman_script" | rman)` but to me, collecting input into a Bash variable already introduces a suspicious smell (and having the script in a variable too, for that matter). – tripleee Dec 21 '17 at 12:57
  • I guess there is no choice. I didn't find any mechanism to better process RMAN errors:( So the only choice is the check the output and the return code. What's bad about having a script in a variable? Could you explain? I always do it so before running I can print some log message `echo "$rman_script"` – damian Dec 21 '17 at 14:31
  • This box is too small for a proper exposition, and I'm reading a bit between the lines in your question; but a frequent error is to prefer storing results in memory over linear and scalable processing in a pipeline, which is usually the most natural way in a shell script. – tripleee Dec 21 '17 at 15:27
  • `tee` lets you print things e.g. to standard error from inside a pipeline. For any nontrivial processing, you are probably inside a control structure like `if` or `while` and can simply `echo "$0: diagnostic" >&2` between other commands which manipulate standard input. – tripleee Dec 21 '17 at 15:30

2 Answers2

2

The here document is no different from other redirections, although the syntax is of course slightly different.

var=$(rman <<\... | tee /dev/stderr
$rman_script
...
)

If this is a representative snippet of your code, you might as well

var=$(rman <<<"$rman_script" | tee /dev/stderr)

By the by, if you genuinely need the script multiple times (why else keep it in a variable?) maybe refactor into a function:

rman_script () {
     rman <<\____HERE
         Actual script
         Probably multiple lines
____HERE
}

var=$(rman_script | tee /dev/stderr)

You'll notice that I use /dev/stderr instead of /dev/tty. Having a script require, and muck with, your tty should probably be avoided unless your script is really short and simple, and only makes sense to use interactively (password manipulation comes to mind as one soenario where it's sometimes hard to avoid).

tripleee
  • 175,061
  • 34
  • 275
  • 318
0
output=$(rman <<RMAN)
$rman_script
RMAN

Note that a HERE-document looks syntactically like a input redirection, only that you have << instead of <. The input will be taken from the subsequent lines.

user1934428
  • 19,864
  • 7
  • 42
  • 87