spawn a child process using ruby - ruby

Am new to ruby.
I have a terminal command to exeute some process and output the result as an xml file.(it is working properly fine via terminal)
cmd = '"C:\Program Files\shark\hark" -f "ains 02:04" -eT xml > test12.xml'
i need to execute this command using ruby code.
But when i tried using ruby code it outputs the xml file and its contents will be zero.if i quit the terminal using CTRL + C i will get the full data inside the xml file
For exiting the child process i tried to kill the process and killed the ruby.exe from the task list .But nothing happned in the xml file.its contents is still zero
code
def execute
cmd = '"C:\Program Files\shark\hark" -f "ains 02:04" -eT xml > test12.xml'
#pid = Process.spawn(cmd)
sleep(100)
exec( 'Taskkill /F /IM ruby.exe' )
end
execute
whats wrong with my code.

I think that Process.wait doesn't support stream redirection. In other words, |, >, >> and < don't work.

Related

How to output an constantly active CMD

I am running an application which opens CMD and connect via API service. Throughout the day new stuff will show up in the CMD and I would like to export that information to txt somewhere and Everytime something new shows up append to the same file, or create a new one. It doesn't really matter
App.exe > /file.txt doesn't really work
Redirection examples
command > filename # Redirect command output to a file (overwrite)
command >> filename # APPEND into a file
command 2> filename # Redirect Errors from operation to a file(overwrite)
command 2>> filename # APPEND errors to a file
command 2>&1 # Add errors to results
command 1>&2 # Add results to errors
command | command # This is the basic form of a PowerShell Pipeline
# In PowerShell 3.0+
command 3> warning.txt # Write warning output to warning.txt
command 4>> verbose.txt # Append verbose.txt with the verbose output
command 5>&1 # Writes debug output to the output stream
command *> out.txt # Redirect all streams (output, error, warning, verbose, and debug) to out.txt
You are not showing any code as to how you are starting/using cmd.exe for your use case. Which just leaves folks trying to help you, to guess. So, redirect of cmd.exe, for example:
$MyOutputFile = C:\MyOutputFile.txt
Start-Process -FilePath c:\windows\system32\cmd.exe -ArgumentList '/c C:\YourCommand.bat' -Wait -NoNewWindow -RedirectStandardOutput $MyOutputFile
Lastly, since you've left us to guess. If you’re launching Process A from PowerShell, but it, Process A is, in turn, launching Process B, then it would be up to Process A to capture or redirect the output of Process B. There’s no way for PowerShell to sub-capture if Process A isn’t doing it.
Resources
About Redirection
How-to: Redirection
PowerShell Redirection Operators
Understanding Streams, Redirection, and Write-Host in PowerShell
Use PowerShell Redirection Operators for Script Flexibility

exec cmd commands using tcl without opening terminal window

I am trying to use exec to run a command such as dir with cmd using tcl code, however the terminal window opens up and I am unable to store the result, when the command has run, into a variable ?
This is what I've been trying so far,
set res [exec cmd.exe /c "dir" &];
When I print out the variable using,
puts $res
I get back just three or four digit codes instead of the actual result when the command was run.
Any help is appreciated.
set res [exec cmd.exe /c "dir" &]
The & at the end of the exec indicates that the command will be processed in the background. The result returned is the process id of the command.
To do what you want, use:
set res [exec cmd.exe /c "dir"]
It would be far more efficient and less resource hungry to use the built-in glob command to get a list of files or search for a file.
set res [glob *.txt]
set res [glob -directory {C:/Program Files} *]
References: exec glob

getting echo from batch script when background task ends

I have this kind of batch file
start /b ruby script.rb && echo done
...
However, it write 'done' immediately after i run the batch file, which is incorrect, as the script took about 5 mins.
So, how to echo done only after the bg task succesfully end?
thank you!
note: I think that && operator work this way if it is not used in batch file nor in usage to run bg task.
start "" /b cmd /c "ruby script.rb && echo done"
Without the quotes the conditional execution command is seen as the continuation of the start command instead of continuation of the ruby command.
As the && is an operator handled by cmd we need to start a new instance.
The "" at the start are needed as the first quoted argument to start is handled as a window title.
note: && is an conditional execution operator. If the previous command does not generate an error then the following command is executed. In this case with the process running in background, probably, &, the command concatenation operator, should be used to know that the script ended.

Close CMD within Ruby

I wrote a function in Ruby that hibernates, restarts, or shuts down the system based on the argument. Here's how it looks:
def sysaction(action)
sleep 0.2
if action == "h"
countdown(60)
`shutdown.exe /h`
elsif action == "r"
countdown(60)
`shutdown.exe -r -f t 00`
elsif action == "s"
countdown(60)
`shutdown.exe -s -f t 00`
end
end
I want to add a piece of code that would exit the parent CMD windows instead. I couldn't find any solution without running the ruby script through a batch file. I tried the following commands:
`exit`
exec `exit`
system('exit')
`cmd /C exit`
But neither seems to work. Any way I can close the window from within Ruby?
Maybe you can use the FreeConsole function:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms683150(v=vs.85).aspx
http://www.ruby-doc.org/gems/docs/w/win32console-1.3.1/Win32/Console/API.html#method-c-FreeConsole
For example:
require 'win32console'
puts 'Hello, world!
# free console so it can be shut after the program terminates.
Win32::Console::API.FreeConsole
One way is to kill all cmd.exe applications:
taskkill /f /im cmd.exe

vbs how to get result from a command line command

I want to get the result of a simple command from the command line (cmd.exe) using a Windows script (.vbs). How is this done? I haven't been able to find a good/simple example or explanation. You could use the "date" or "time" command to provide an example with.
Such as:
P.S. I am able to write the script code that opens cmd.exe and sends the command.
Thanks!
When in doubt, read the documentation. You probably want something like this:
Set p = CreateObject("WScript.Shell").Exec("%COMSPEC% /c date /t")
Do While p.Status = 0
WScript.Sleep 100
Loop
WScript.Echo p.StdOut.ReadAll
Edit: When using Exec() you pass input via the .StdIn descriptor, not via SendKeys() (which is a rather unreliable way of passing input anyway).
%COMSPEC% is a system environment variable with the full path to cmd.exe and the /c option makes cmd.exe exit after the command (date /t in the example) is finished.
If the command indicates success/failure with an exit code, you can check the ExitCode property after the command finished.
If p.Status <> 0 Then WScript.Echo p.ExitCode
Edit2: Instead of using atprogram interactively, can you construct commandlines that will perform particular tasks without user interaction? With non-interactive commandlines something like this might work:
prompt = "C:\>"
atprogram_cmdline_1 = "atprogram.exe ..."
atprogram_cmdline_2 = "atprogram.exe ..."
'...
Function ReadOutput(p)
text = ""
Do Until Right(text, Len(prompt)) = prompt
text = text & p.StdOut.Read(1)
Loop
ReadOutput = text
End Function
Set cmd = CreateObject("WScript.Shell").Exec("%COMSPEC% /k")
ReadOutput cmd ' skip over first prompt
cmd.StdIn.WriteLine(atprogram_cmdline_1)
WScript.Echo ReadOutput(cmd)
cmd.StdIn.WriteLine(atprogram_cmdline_2)
WScript.Echo ReadOutput(cmd)
'...
cmd.Terminate ' exit CMD.EXE
%COMSPEC% /k spawns a command prompt without running a command. The /k prevents it from closing. Because it isn't closing automatically, you can't use the While p.Status = 0 loop here. If a command needs some time to finish, you need to WScript.Sleep a number of seconds.
Via cmd.StdIn.WriteLine you can run commandlines in the CMD instance. The function ReadOutput() reads the output from StdOut until the next prompt appears. You need to look for the prompt, because read operations are blocking, so you can't simply say "read all that's been printed yet".
After you're finished you quit CMD.EXE via cmd.Terminate.

Resources