1

I am writing Powershell script, which will essentially be a menu driven utility for doing random tasks. One of the feature includes, to display java version. I am using REPLto have it in continues loop. My issue is that the Java version is just not being displayed on the screen. Can anyone please help me with the reason for this or a work around ? Below is the code:



 enum Outcome
{
    Continue
    Quit
}
 
 Class Opatch_Manager {
     
     REPL() {

        while($this.ShowMenu() -eq 'Continue') {
            $this.Print()
        }
    }

    Print() {
        Write-Host "Test"
    }
    
   [String] ShowJava() {
     java -version
    }
   
    [Outcome] ShowMenu() {
        $this.ShowJava() 
        return [Outcome]::Quit
     }
     
 }
 
 $obj = New-Object Opatch_Manager
 $obj.REPL()
 

1 Answer 1

1

Unlike direct use of commands in scripts and functions, methods in PowerShell custom classes must use return in order to produce output (and the method must declare a suitable return type).

Similarly, stderr output - which is what java -version produces - isn't automatically passed through.

Note:

  • Using java --version instead, i.e two leading -, produces stdout instead, so that
    return java --version would produce output, albeit probably not in the expected format - see below, which discusses the formatting aspect as well as the general case when stderr output must be captured.

Thus, combine return with a 2>&1 redirection (simplified example):

class Foo {

  [String] ShowJava() {
    return (java -version 2>&1) -join "`n"
   }

}  

[Foo]::new().ShowJava() 
  • 2>&1 redirects stderr (2) output to PowerShell's success output stream (the analog to stdout) so that return can return it.

  • -join "`n" is used to return the output lines as a single, multi-line string.

    • This is necessary, because your method is declared as [string], whereas output from an external program is reported line by line by PowerShell, which becomes an array when collected, and PowerShell stringifies arrays (typically) as a single-line string, namely by concatenating the (stringified) elements with spaces.

      • Note: The simpler java -version 2>&1 | Out-String works in principle, but Out-String unfortunately invariably adds a trailing newline to the resulting string - see GitHub issue #14444 for a discussion.
    • The alternative is to declare your method as [string[]] - then
      return java -version 2>&1 will do (and an array of lines is returned)

Sign up to request clarification or add additional context in comments.

2 Comments

I have a small question though, why does java -version produces stderr, and java --version stdout?
@PrateekJaiswal - that is a good question, and not being a Java user I can only guess: --version is the syntax used by GNU utilities (the CLIs that come with most Linux distros), and these utilities are expected to print the version information to stdout. Perhaps java wants to align with these utilities, and perhaps the Java syntax form, -version, has always output to stderr instead (for reasons unknown to me).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.