4

In PowerShell I can do this:

function Get-Foo()
{
   Write-Host "Calculating result..."
   return 42
}

$x = Get-Foo
Write-Host "The answer is $x" # output: The answer is 42

So Calculating result.. is output to the console, but it's not present in the pipeline so I can just take the method's "return value" and it works

However in bash I don't have Write-Host and something like this won't work:

function getfoo {
   echo "Calculating result..."
   echo "42"
}

x=$(getfoo)
echo $x # output will include "Calculating result..."

I realize I can save to a file and print after, just wondering if there's a more elegant alternative

Ohad Schneider
  • 36,600
  • 15
  • 168
  • 198

1 Answers1

4

Redirect your output to /dev/tty to print directly to the terminal:

echo "Calculating result..." > /dev/tty

Simple example:

# Only '42' is stored in $output
$ output=$(echo "Calculating result..." > /dev/tty; echo 42)
Calculating result...

Another, probably better option - if you want to give the caller the option to still capture - or silence - the status information - is to redirect to stderr, with >&2:

# Only '42' is stored in $output
$ output=$(echo "Calculating result..." >&2; echo 42)
Calculating result...
mklement0
  • 382,024
  • 64
  • 607
  • 775
  • I'd argue sending something that isn't an error to `stderr` is someone unintuitive. I like the redirecting to `/dev/tty` though. – mikemaccana May 11 '20 at 16:49
  • @mikemaccana Outputting status information to stderr is common practice in the Unix world (`git` being a prominent example). It's not ideal, but in the absence of the availability of additional streams it is the best choice, because the problem with outputting to `/dev/tty` is that you can neither suppress nor capture such output. – mklement0 May 11 '20 at 17:15
  • That's a good counterexample. This still feels like a workaround for bash not separating content from presentation - the OP would be better served with `python` (if they wanted to remove the requirement to install anything) or stick with `pwsh` if they were happy to ask Unix users to install it. – mikemaccana May 12 '20 at 13:33
  • 1
    @mikemaccana Traditional shells such as `bash` and `cmd.exe` rely on the available output streams at the _system_ level, which are limited to _two_ output streams: stdout and stderr. Hence, anything _other than data_ must be sent to stderr. Process-internally, PowerShell commendably provides _six_ purpose-specific output streams, but it too must fit into the two-output-streams world when communicating with the outside world, [which it does a poor job of](https://github.com/PowerShell/PowerShell/issues/7989#issuecomment-430854508). – mklement0 May 14 '20 at 01:58