How use stdout variable of Mixlib:ShellOut


#1

Hi partners,

I want to use Mixlib:ShellOut to knowing if tomcat is running or stopped. I am using the following powershell commands: (Get-Service Tomcat7).Status -eq "Running" and (Get-Service Tomcat7).Status -eq "Stopped" that return True or False and I want to get these values. According to documentation the output of commands is placed in stdout variable after run the command with run_command function. Then, I make the following functions:

  def isRunning?
    tomcat = Mixlib::ShellOut.new("(Get-Service Tomcat7).Status -eq \"Running\"")
    tomcat.run_command
    if tomcat.stdout === "True"
      return true
    else
      return false
    end
  end

  def isStop?
    tomcat = Mixlib::ShellOut.new("(Get-Service Tomcat7).Status -eq \"Stopped\"")
    tomcat.run_command
    if tomcat.stdout === "True"
      return true
    else
      return false
    end
  end

However, if I do:

  puts isRunning?
  puts isStop?

Both functions return false, then how I can use the stdout variable to know the result of command ?

Any help pls.


#2

If you are issuing powershell commands, use the dsl helper powershell_out instead of Mixlib:ShellOut. Mixlib:ShellOut invokes command on the standard shell which is cmd.exe on windows. So the problem is likely that powershell commands run via cmd is not producing anything on standard out but you may find something on standard error instead.

You can use powershell_out just as you would Mixlib:Shellout:

cmd = powershell_out!(cmd_str)
Chef::Log.info(cmd.stdout)
Chef::Log.info(cmd.stderr)

#3

Thanks @Matt_Wrock, now I am testing but I get this error:

[2016-09-20T17:42:44-05:00] INFO: Debe proporcionar una expresiî de valor a la derecha del operador '-eq'.

En l®ea: 1 Carcter: 33

+ (Get-Service Tomcat7).Status -eq <<<<  Running

    + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException

    + FullyQualifiedErrorId : ExpectedValueExpression 

With this code:

cmd = powershell_out!("(Get-Service Tomcat7).Status -eq \"Running\"")
Chef::Log.info(cmd.stdout)
Chef::Log.info(cmd.stderr)

I type in powershell (Get-Service Tomcat7).Status -eq "Running" and return True

Any suggestion.


#4

this looks like a quote parsing bug and looking at the code for powershell_out it is indeed a bug. To work around it, use single quotes around Running.


#5

Thanks @Matt_Wrock the code run with single quotes. However, I need to put this code in my helpers.rb file and I believe I need to include any gem because it return an error about powershell_out. Then, what gem I need to include ?


#6

powershell_out is part of the recipie dsl and implemented to be invoked from inside recipie code. I think you could execute it in a library by including: require "chef/mixin/powershell_out" at the top of the library file.


#7

Doesn’t work, any other suggestion ?


#8

Hi, I believe I need download the gem, what is its name ?

Pls help or suggestions.


#9

powershell_out is in the chef gem. What’s the error you receive when requireing it?


#10

I am using, this code in helpers.rb file:

# Function to know if tomcat is Running
  def self.isRunning?
    tomcat = powershell_out!("(Get-Service Tomcat7).Status -eq \"Running\"")
    if tomcat.stdout[/True/]
      return true
    else
      return false
    end
  end

# Method to pause execution while tomcat start
  def self.waitStart
    if isRunning?
      agent = Mechanize.new
      agent.user_agent_alias = 'Windows Chrome'
    	begin
      	agent.read_timeout = 5 #set the agent time out
      	page = agent.get('http://localhost:8080')
      	agent.history.pop()   #delete this request in the history
        Chef::Log.info("Tomcat7 Started")
    	rescue
    		Chef::Log.info("Wait for Tomcat7 to continue...")
    		agent.shutdown
    		agent = Mechanize.new { |agent| agent.user_agent_alias = 'Windows Chrome'}
    		agent.request_headers
    		sleep(150)
    		retry
    	end
    end
  end

An get this error:

* windows_service[Tomcat7] action start (up to date)
* ruby_block[wait for tomcat to start] action run

  ================================================================================
  Error executing action `run` on resource 'ruby_block[wait for tomcat to start]'
  ================================================================================

  NoMethodError
  -------------
  undefined method `powershell_out!' for Tomcat:Module

  Resource Declaration:
  ---------------------
  # In C:/chef/cache/cookbooks/deploy_war/recipes/prepare.rb

   42: ruby_block 'wait for tomcat to start' do
   43:   block do
   44:     Tomcat.waitStart
   45:   end
   46: end
   47:

  Compiled Resource:
  ------------------
  # Declared in C:/chef/cache/cookbooks/deploy_war/recipes/prepare.rb:42:in `from_file'

  ruby_block("wait for tomcat to start") do
    action [:run]
    retries 0
    retry_delay 2
    default_guard_interpreter :default
    block_name "wait for tomcat to start"
    declared_type :ruby_block
    cookbook_name "deploy_war"
    recipe_name "prepare"
    block #<Proc:0x5ed2290@C:/chef/cache/cookbooks/deploy_war/recipes/prepare.rb:43>
  end

The function to wait for tomcat is working, the problem is the powershell_out gem


#11

I should have recommended include not require. Use include Chef::Mixin::PowershellOut at the top of your library file


#12

Thanks @Matt_Wrock, it solve my problem !

Regards.


#13

Thanks, this helped me! This method is nice to use output from my PowerShell scripts in other parts of my recipes.