perl using open3 to write to STDIN and capture STDOUT and STDERR - windows

I'm using a Windows x64 machine and am trying to capture the STDOUT and STDERR streams from a command. I also have to write to the command's STDIN. I'm trying to use perl's IPC::Open3 for this, with no luck. I'm using the script posted here and the command as this script here. I of course replaced the $cmd variable with "perl test.pl" for Windows.
It's supposed to print 'StdOut!' and 'StdErr!', along with the pid, but I only get the PID. I don't know if it is because of my operating system, or because the thread is 10 years old (no biggie, Perl 5 is almost 18, right?). Another monk posted this script to fix any problems in the other one, but on my computer it never exits.
Can anyone give me a working example of using open3 to start a command in perl, write to its STDIN, and capture both its STDERR and its STDOUT?

select only works for sockets in Windows; it doesn't work on pipes. You could create sockets instead and pass those to open3 instead of letting it create pipes for you (as seen here), but I suggest that you use a higher-level module such as IPC::Run instead. open3 is a rather low-level function.

Related

Is it possible to capture output from a system command and redirect it?

What I would like to do is:
run a ruby script...
that executes a shell command
and redirects it to a named pipe accessible outside the script
from the system shell, read from that pipe
That is, have the Ruby script capture some command output and redirect it in such a way that it's connectable to from outside the script?
I want to mention that the script cannot simply start and exit, since it's a REPL. The idea is that using the REPL you would be able to run a command and redirect its output elsewhere to consume it.
Using abort and an exit message, will pass the message to STDERR (and the script will fail with exit code 1). You can pass this shell command output in this way.
This is possibly not the only (or best) way, but it has worked for me in the past.
[edit]
You can also redirect the output to a file (using standard methods), and read that file outside the ruby script.
require 'open3'
stdin, stderr, status = Open3.capture3(commandline)
stdin.chomp #Here, you should ge
Incase, if someone wanted to use you can get the output via stdin.chomp

How to read from terminal in lazarus on ubuntu

Lazarus can run bash scripts and commands. How to get the output of an executed command as string and later use it, for example print it with ShowMessage? Thanks!
Summary:
use the tprocess class from unit process, that allows to trap console output using pipes.
for straightforward cases use the Runcommand helper functions (also in process, wrap tprocess for simple cases)
Be aware that while you see console output as one stream, in fact there might be two (stdout and stderr)

How to read stdout unbuffered with Open#popen3 in Ruby

I'm running a process using popen3, and trying to read the stdout stream. I want to be able to detect each character as it's put into stdout, but even using stdout.getc, I'm only able to get any output once there's a newline.
Any tips? I've seen this answered with stdin.getc, but not stdout.
The problem you have is that most programs when run through a pipe, which is what happens with popen, will be run using buffered output.
But what you are looking for is unbuffered output. Unbuffered output only happens when the proccess is attached to a PTY. I.e. a shell.
When you attach the process to a pipe the output will be buffered unless the process is explicitly calling flush during its output processing.
You have a few options:
If you have control over the source code that you run with popen then force a flush call on stdout after each output sequence.
You could try and run the command under stdbuf -o0, which tries to force unbuffered output.
See this answer:
Force line-buffering of stdout when piping to tee.
However that is not guaranteed to work for all programs.
You could try to use the Ruby PTY library instead of popen to make the program run under a pseudo-terminal, and hence run unbuffered. See this answer:
Continuously read from STDOUT of external process in Ruby
Option 3 is most likely to work with any program you want to run and monitor, while the other options may or may not work depending on the program you are running and if you have access to the source code of that program.

Interact with long-running bash script. Automatic inputs when certain outputs appears

echo "yes\yes\oops" | program doesn't work well for a long-running program.
I can think of redirect the output of program to a file, then use a loop to grep that file until certain output appears. But is there any better idea?
If you prefer/are stuck with bash, perhaps you are looking for expect?
More on that here: http://wiki.tcl.tk/11583
Write a Python, Perl, Ruby or script in another language to interact with the program. In Python you'd use subprocess. In Perl you'd use popen(). Read the program's stdout line-by-line and match against known prompts, replying with the desired response by writing to the program's stdin.
You can do the same in bash, but I personally prefer not to.

Piping stdin to ruby script via `myapp | myscript.rb`

I have an app that runs continuously, dumping output from a server and sending strings to stdout. I want to process this output with a Ruby script. The strings are \n-terminated.
For example, I'm trying to run this on the command line:
myapp.exe | my_script.rb
...with my_script.rb defined as:
while $stdin.gets
puts $_
end
I ultimately am going to process the strings using regexes and display some summary data, but for now I'm just trying to get the basic functionality hooked up. When I run the above, I get the following error:
my_script.rb:1:in `gets': Bad file descriptor (Errno::EBADF)
from my_script.rb:1
I am running this on Windows Server 2003 R2 SP2 and Ruby 1.8.6.
How do I continuously process stdin in a Ruby script? (Continuously as in not processing a file, but running until I kill it.)
EDIT:
I was able to make this work, sort of. There were several problems standing in my way. For one thing, it may be that using Ruby to process the piped-in stdin from another process doesn't work on Windows 2003R2. Another direction, suggested by Adrian below, was to run my script as the parent process and use popen to connect to myapp.exe as a forked child process. Unfortunately, fork isn't implemented in Windows, so this didn't work either.
Finally I was able to download POpen4, a RubyGem that does implement popen on Windows. Using this in combination with Adrian's suggestion, I was able to write this script which does what I really want -- processes the output from myapp.exe:
file: my_script.rb
require 'rubygems'
require 'popen4'
status =
POpen4::popen4("myapp.exe") do |stdout, stderr, stdin, pid|
puts pid
while s = stdout.gets
puts s
end
end
This script echoes the output from myapp.exe, which is exactly what I want.
Try just plain gets, without the $stdin. If that doesn't work, you might have to examine the output of myapp.exe for non-printable characters with another ruby script, using IO.popen.
gets doesn't always use stdin but instead tries to open a file.
See SO.
Try executing your Ruby script by explicitly calling ruby:
myapp.exe | ruby my_script.rb
I've experienced some odd behavior using stdin in Ruby when relying on Windows to invoke the correct program based on the file associations.

Resources