Using standard io stream:stdin and stdout in a matlab exe - windows

Question
I want it to 'listen' to the standard input stream in a running (compiled) Matlab executable.
This is how I believe it is done in c or a similar language:
#include stdio.h
fgets(line, 256, stdin)
Or more elaborately, it it can be used as such:
if (!fgets(line, 256, stdin))
return;
if (line[0] == '\n')
continue;
sscanf(line, "%s", command);
Answer
For completeness I will leave the background and notes intact, but with the help of Amro and EitanT I have managed to work it out.
Background
I have found how to do this in other languages, and here are some instructions for the compilation process.
However, I have not found anywhere how to 'listen' to the input in Matlab.
The closest I have come is this description of C-like IO in Octave, but I cannot make progress with this as I looking for a solution in MATLAB.
Note that altering or wrapping the program that sends the data over the stream is not possible, and that I would prefer a pure MATLAB solution rather than wrapping my entire program. If I were to call a trivial function from MATLAB in a different language that would be ok.
What have I tried?
I tried a few functions from the command window like fgets(0) (fid = 0 seems to be the id corresponding to stdin (as mentioned by #EitanT and seen when trying fopen(0)) )but it just returns:
Operation is not implemented for requested file identifier.
I have also considered using the option in MATLAB to invoke system commands or execute java / perl commands, but so far without luck. I am also not sure whether these would still work after compilation.
Furthermore I attempted to use input('prompt','s') this works when I open the program via cmd, but does not do anything until I hit enter. (Which the program that I listen to of course will never do, in the best case I can get \n at the end of each line).
I also tried out waitinput from File Exchange but I think this is a dead end as it did not catch anything and seems to perform quite poorly.
Notes
I am using Windows 7 and MATLAB 2012b.
I found popen on File Exchange but that does not seem to be available for Windows.
When I simply type something like 'show me' this is properly sent to the standard output stream.

Let me illustrate with a toy example. Consider the following MATLAB function:
greet.m
function greet()
str = input('Enter your name: ','s');
fprintf('Hello %s\n',str)
end
Now lets compile it into a standalone application. Note that if you use the deploytool tool, make sure to choose "Console application" NOT "Windows standalone application" as target. The latter apparently produces an executable where the standard input is connected to the system shell not the MATLAB command prompt..
If you prefer to directly compile it yourself, use the following invocation:
mcc -o hello -W main:hello -T link:exe -N -v greet.m
(For reference, the "Windows app" target issues -W WinMain:hello instead)
Running the executable produces:
C:\> hello
Enter your name: Amro
Hello Amro
where the input from the keyboard is correctly handled.

It turns out that input reads the standard input stream.
The reason why I failed to collect my inputs, is because I was using it as follows:
input('prompt','s')
As a result the string 'prompt' was sent to the program calling my application, and as it considered this an invalid response/request it did not send anything.
I have succeeded in making a small test program, and unlike I suspected before it is NOT a problem that the other application doesn't hit enter after sending a command.
The general solution
This is the way I have my current setup,
while 1
stdin = input('','s'); % Note the empty first argument
if ~isempty(stdin)
stdout = process_input(stdin);
stdout % Displaying the result (And thus sending it to stdout)
end
end

Related

Golang get command tty output

I'm using go's exec Run command to get command output, which works great when the command 'Stdout' field is set to os.Stdout, and the error is sent to os.Stderr.
I want to display the output and the error output to the console, but I also want my program to see what the output was.
I then made my own Writer type that did just that, wrote both to a buffer and printed to the terminal.
Here's the problem—some applications change their output to something much less readable by humans when it detects it's not writing to a tty. So the output I get changes to something ugly when I do it in the latter way. (cleaner for computers, uglier for humans)
I wanted to know if there was some way within Go to convince whatever command I'm running that I am a tty, despite not being os.Stdout/os.Stderr. I know it's possible to do using the script bash command, but that uses a different flag depending on Darwin/Linux, so I'm trying to avoid that.
Thanks in advance!
The only practical way to solve this is to allocate a pseudo terminal (PTY) and make your external process use it for its output: since PTY is still a terminal, a process checking whether it's connected to a real terminal thinks it is.
You may start with this query.
The github.com/creack/ptyis probably a good starting point.
The next step is to have a package implementing a PTY actually allocate it, and connect "the other end" of a PTY to your custom writer.
(By the way, there's no point in writing a custom "multi writer" as there exist io.MultiWriter).

How to route Matlab input to specific DOS cmd input?

I have a Matlab script that uses the dos command to open an exe. This exe pauses awaiting user input. For this project I need everything to be scripted and dynamic, so matlab has to be able to continue running its script, dynamically determine what to input to the running exe, and then input it.
So far, I have been able to get the exe to run in the background and let the matlab script continue by using dos('test.exe &'), but I cant get then get matlab to send inputs to the running exe. I have tried batch files and I still run into the same issue, which is how do I automate the sending of inputs to the cmd line when the cmd line exe running is paused awaiting user input?
My best guess would be that I need to reroute the standard output of matlab to the standard input of a specific, already open instance of cmd, but I have no idea how to do that and have been unable to find anything so far on the internet. Any insight would be greatly appreciated, thanks.
There is a way. It's just not elegant.
When you call a program with &, its window appears in the foreground and has focus (at least on my system). So you can send it keyboard events from Matlab using the java.awt.Robot class.
If you need to automatize the conversion from characters to key presses, you probably need a big switch statement along these lines. The following example defines the events manually, which is only practical for small inputs.
robot = java.awt.Robot;
dos('copy con &'); % open MS-DOS Window that will just echo the input text
pause(1) % allow some time for the external program to start up
robot.keyPress(java.awt.event.KeyEvent.VK_SHIFT);
robot.keyPress(java.awt.event.KeyEvent.VK_H);
robot.keyRelease(java.awt.event.KeyEvent.VK_H);
robot.keyRelease(java.awt.event.KeyEvent.VK_SHIFT);
robot.keyPress(java.awt.event.KeyEvent.VK_E);
robot.keyRelease(java.awt.event.KeyEvent.VK_E);
robot.keyPress(java.awt.event.KeyEvent.VK_L);
robot.keyRelease(java.awt.event.KeyEvent.VK_L);
robot.keyPress(java.awt.event.KeyEvent.VK_L);
robot.keyRelease(java.awt.event.KeyEvent.VK_L);
robot.keyPress(java.awt.event.KeyEvent.VK_O);
robot.keyRelease(java.awt.event.KeyEvent.VK_O);
robot.keyPress(java.awt.event.KeyEvent.VK_SHIFT);
robot.keyPress(java.awt.event.KeyEvent.VK_1);
robot.keyRelease(java.awt.event.KeyEvent.VK_1);
robot.keyRelease(java.awt.event.KeyEvent.VK_SHIFT);
robot.keyPress(java.awt.event.KeyEvent.VK_ENTER);
robot.keyRelease(java.awt.event.KeyEvent.VK_ENTER);
Here's an example run:
Unfortunately there is no way to do what you are describing.
The fact that the external program pauses and awaits for an input is a serious challenge: for Matlab, there is just a program running in the background, and it has no way to "know" that this program is awaiting for an input at a given moment.
Then, another issue is that there is no "Matlabish" way to send a command to a running thread send in the background. edit The solution proposed by Luis is ugly but works for this.
If you can modify the external program, then you can certainly avoid the problem by defining a different protocol for input tranfer, like TCP/IP. But it's not a general answer and I guess you don't have such a possibility.
You could try to use Sikuli for this, if you are really desperate.
Thanks to the wonderful explanation by Luis Mendo, I have quickly put together a function that takes a string input and outputs the proper robot commands. It works for me!
function typeStringOut(robot,text)
keyMatch = {};
keyMatch(1,:) = {'`','-','=',',','.','/',';','[',']','\'};
keyMatch(2,:) = {'~','_','+','<','>','?',':','{','}','|'};
keyMatch(3,:) = {'BACK_QUOTE','MINUS','EQUALS','COMMA','PERIOD','SLASH','SEMICOLON','OPEN_BRACKET','CLOSE_BRACKET','BACK_SLASH'};
numKeyMatch = {};
numKeyMatch(1,:) = {'1','2','3','4','5','6','7','8','9','0'};
numKeyMatch(2,:) = {'!','#','#','$','%','^','&','*','(',')'};
for i=1:length(text)
if isstrprop(text(i),'alpha')
if isstrprop(text(i),'upper')
robot.keyPress(java.awt.event.KeyEvent.VK_SHIFT);
end
eval(['robot.keyPress(java.awt.event.KeyEvent.VK_',upper(text(i)),');']);
if isstrprop(text(i),'upper')
robot.keyRelease(java.awt.event.KeyEvent.VK_SHIFT);
end
elseif isstrprop(text(i),'digit')
eval(['robot.keyPress(java.awt.event.KeyEvent.VK_',text(i),');']);
elseif isstrprop(text(i),'wspace')&&strcmp(text(i),' ')
eval('robot.keyPress(java.awt.event.KeyEvent.VK_SPACE);');
elseif isstrprop(text(i),'punct')||isstrprop(text(i),'graphic')
switch text(i)
case {'`','-','=',',','.','/',';','[',']','\'}
matchIdx = strcmp(keyMatch(1,:),text(i));
eval(['robot.keyPress(java.awt.event.KeyEvent.VK_',keyMatch{3,matchIdx},');']);
case {'~','_','+','<','>','?',':','{','}','|'}
robot.keyPress(java.awt.event.KeyEvent.VK_SHIFT);
matchIdx = strcmp(keyMatch(2,:),text(i));
eval(['robot.keyPress(java.awt.event.KeyEvent.VK_',keyMatch{3,matchIdx},');']);
robot.keyRelease(java.awt.event.KeyEvent.VK_SHIFT);
case {'!','#','#','$','%','^','&','*','(',')'}
robot.keyPress(java.awt.event.KeyEvent.VK_SHIFT);
matchIdx = strcmp(numKeyMatch(2,:),text(i));
eval(['robot.keyPress(java.awt.event.KeyEvent.VK_',numKeyMatch{3,matchIdx},');']);
robot.keyRelease(java.awt.event.KeyEvent.VK_SHIFT);
otherwise
error([text(i),' is unknown character']);
end
elseif strcmp(text(i),'<')||strcmp(text(i),'>')
robot.keyPress(java.awt.event.KeyEvent.VK_SHIFT);
matchIdx = strcmp(keyMatch(2,:),text(i));
eval(['robot.keyPress(java.awt.event.KeyEvent.VK_',keyMatch{1,matchIdx},');']);
robot.keyRelease(java.awt.event.KeyEvent.VK_SHIFT);
else
error([text(i),' is unknown character']);
end
end
robot.keyPress(java.awt.event.KeyEvent.VK_ENTER);
robot.keyRelease(java.awt.event.KeyEvent.VK_ENTER);
end

clear screen in Fortran

I've been searching for a considerably long time for this. Does anyone know how to clear the screen in a console app in Fortran language?
any help will be very much appretiated!
Fortran, qua Fortran, knows nothing of such concepts as screens or keyboards or, for that matter, computers. There is, therefore, no language-standard way of clearing a screen from Fortran. You will have to find some platform-dependent approach.
Most Fortran compilers have some way of doing this, for example Intel Fortran provides the SYSTEM function.
Contrary to others I would not call SYSTEM() (standard Fortran 2008 alternative is execute_command_line()) but I would print right ANSI escape code http://en.wikipedia.org/wiki/ANSI_escape_code:
print *, achar(27)//"[2J"
This will be much faster than calling SYSTEM().
This works in typical Linux terminals, but will not work in the MS Windows terminal.
Another more practical reference how to use the escape code is http://www.lihaoyi.com/post/BuildyourownCommandLinewithANSIescapecodes.html
In Fortran 90/95 your best option is the system command which is a vendor supplied extension (i.e., not part of the F90/95 standard so some obscure Fortran compilers may not have it but all major ones do).
$ cat clear.f90
program
call system('clear')
end
$ gfortran clear.f90 -o clear
$ ./clear
It depends on your specific sytem and compiler. There is no general way. Fortran doesn't know about specific hardware devices like terminal screens and printers. (Neither do most other languages). The details depend entirely on your specific system.
My advice would be to clear the terminal by invoking the relevent script via the command line - but this is not nice. it is generally more portable to write the output to an ordinary text file and then execute appropriate system commands to print that file to screen. This way you can manipulate the file as you wish...
See here for a simalar question from which these some of the above text was salvaged.
In Fortran ACHAR(N) returns the ASCII of N, so my preferred method would be:
WRITE(*,'(2f15.9,A5)',advance='no') float1,float2,ACHAR(13)
ACHAR(13) returns carriage return character \r in Python. So after printing, it returns the cursor to the beginning of the line where it can be overwritten.
After you are out of the loop you can use CALL SYSTEM('clear') to clean the screen.
This is helpful since CALL SYSTEM('clear') is slower and uses a lot of CPU, you can check this by replacing the above method with
WRITE(*,'(2f15.9)',advance='no') float1,float2;CALL SYSTEM('clear')
and check the difference in time taken in loops.
This Works For Me in FTN95
program
call system('CLS')
end
I found yet another way to clear screen in UNIX like systems by printing the output of clear command (from manual of clear command which states you can write the output to a file and then cat it to clear the screen)
So better way is to clear > temp.txt and use the characters in files in a print statement
Although both do the same thing, calling SYSTEM("foo") is very very (100+ times) slower than directly printing those characters
For example:
program clear
implicit none
INTEGER::i
do i = 1, 1000
print *, "Test"
call system("clear")
enddo
end program clear
This program takes anywhere between 3.1 to 3.4 seconds.
But instead of calling system, if I directly print the characters like this :
program clear
implicit none
INTEGER::i
do i = 1, 1000
print *, "Test"
print *, "[H[2J[3J"
enddo
end program clear
This produces the exact same result but takes anywhere between 0.008 to 0.012 seconds (8 to 12 ms)
In fact, running the second loop 100,000 is faster than CALL SYSTEM("clear") 1000 times
EDIT: Don't copy-paste from here, it won't work, (characters are replaced on StackOverflow)
Just use clear > file and copy the contents of the file into a print statement
Screenshot of actual code(from preview):
These characters aren't supported I guess, They disappear in the answers (They work fine in preview)

How do I write to the console regardless of whether or not the user uses `|` or `>` operators on the shell?

I wrote a program in Ruby and have been writing all data to the console with puts.
If I run my.rb from the console I can redirect the stream to a file both with > and |.
How should I change stdout in order for data to be written to the Windows console?
The whole idea of those symbols is to allow users of your app to redirect the output to their desired place. This is useful for logging, filtering, and any number of other applications where you want the output of one program to be the input of another program or file. It's facilitates a form of inter-process communication that often isn't possible otherwise.
Essentially, unless you can more clearly define the reason you want to do this (a specific case where this is useful and desirable) you should not try to do this, nor am I sure it's even possible, because those symbols operate at the shell level. I don't think there is anything within the scope of Ruby that you can do what will have any effect whatsoever on where the output goes. The shell (after it's already left your Ruby program) is capturing that output and redirecting it. By that point, that data/output is already out of the control of your Ruby app.
If you are trying to differentiate from real "output" and error messages that the user should see, you can instead send output to the standard error output with something like:
$stderr << 'oh noes!'
The standard error output is redirected independently from the standard output.

2-way communication with background process (I/O)

I have a program that runs in the command line (i.e. $ run program starts up a prompt) that runs mathematical calculations. It has it's own prompt that takes in text input and responds back through standard-out/error (or creates a separate x-window if needed, but this can be disabled). Sometimes I would like to send it small input, and other times I send in a large text file filled with a series of input on each line. This program takes a lot of resources and also has a large startup time, so it would be best to only have one instance of it running at a time. I could keep open the program-prompt and supply the input this way, or I can send the process with an exit command (to leave prompt) which just prints the output. The problem with sending the request with an exit command is that the program must startup each time (slow ...). Furthermore, the output of this program is sometimes cryptic and it would be helpful to filter the output in some way (eg. simplify output, apply ANSI colors, etc).
This all makes me want to put some 2-way IO filter (or is that "pipe"? or "wrapper"?) around the program so that the program can run in the background as single process. I would then communicate with it without having to restart. I would also like to have this all while filtering the output to be more user friendly. I have been looking all over for ideas and I am stumped at how to accomplish this in some simple shell accessible manor.
Some things I have tried were redirecting stdin and stdout to files, but the program hangs (doesn't quit) and only reads the file once making me unable to continue communication. I think this was because the prompt is waiting for some user input after the EOF. I thought that this could be setup as a local server, but I am uncertain how to begin accomplishing that.
I would love to find some simple way to accomplish this. Additionally, if you can think of a way to perform this, do you think there is a way to also allow for attaching or detaching to the prompt by request? Any help and ideas would be greatly appreciated.
You could create two named pipes (man mkfifo) and redirect input and output:
myprog < fifoin > fifoout
Then you could open new terminal windows and do this in one:
cat > fifoin
And this in the other:
cat < fifoout
(Or use tee to save the input/output as well.)
To dump a large input file into the program, use:
cat myfile > fifoin

Resources