Program running not in order - ruby

I tried running this simple code:
puts 4
i = gets
puts i
It's "working", but the console asks for a string and just then it prints 4 and i

Add a flush call before gets:
$stdout.flush

Instead of explicitly calling $stdout.flush:
$stdout.sync = true

Works in order for me using ruby 1.8.7, 1.9.2 and ree. What version of ruby and operating system are you on?

What are you hoping to accomplish here ?
Normally the interpreter gathers all data before presenting you with the output. It's simply isnt bash :)

I guess you may be hit by output buffering. But your code example does not show how the program might "ask" for input, so I guess that you type answer just before ruby starts. Then your ruby program reads the input from input buffers, as the data is not read directly from the keyboard.
Are you sure that your problem is caused by exactly this code you have shown us?
Usually problems with data shown on terminal in wrong order are caused by using two different output streams: STDIN and STDERR for example. Each stream may decide to flush its data at different times.
if you want to make sure the text is displayed before something happens (as in this example) use the 'flush' command, as Yossi suggests.

Related

Garbage/control characters observed in output from Paramiko when get_pty=True for Windows2019/2022 (CygwinOpenssh) [duplicate]

I am using Python's Paramiko library to SSH a remote machine and fetch some output from command-line. I see a lot of junk printing along with the actual output. How to get rid of this?
chan1.send("ls\n")
output = chan1.recv(1024).decode("utf-8")
print(output)
[u'Last login: Wed Oct 21 18:08:53 2015 from 172.16.200.77\r', u'\x1b[2J\x1b[1;1H[local]cli#BENU>enable', u'[local]cli#BENU#Configure',
I want to eliminate, [2J\x1b[1;1H and u from the output. They are junk.
It's not a junk. These are ANSI escape codes that are normally interpreted by a terminal client to pretty print the output.
If the server is correctly configured, you get these only, when you use an interactive terminal, in other words, if you requested a pseudo terminal for the session (what you should not, if you are automating the session).
The Paramiko automatically requests the pseudo terminal, if you used the SSHClient.invoke_shell, as that is supposed to be used for implementing an interactive terminal. See also How do I start a shell without terminal emulation in Python Paramiko?
If you automate an execution of remote commands, you better use the SSHClient.exec_command, which does not allocate the pseudo terminal by default (unless you override by the get_pty=True argument).
stdin, stdout, stderr = client.exec_command('ls')
See also What is the difference between exec_command and send with invoke_shell() on Paramiko?
Or as a workaround, see How can I remove the ANSI escape sequences from a string in python.
Though that's rather a hack and might not be sufficient. You might have other problems with the interactive terminal, not only the escape sequences.
You particularly are probably not interested in the "Last login" message and command-prompt (cli#BENU>) either. You do not get these with the exec_command.
If you need to use the "shell" channel due to some specific requirements or limitations of the server, note that it is technically possible to use the "shell" channel without the pseudo terminal. But Paramiko SSHClient.invoke_shell does not allow that. Instead, you can create the "shell" channel manually. See Can I call Channel.invoke_shell() without calling Channel.get_pty() beforehand, when NOT using Channel.exec_command().
And finally the u is not a part of the actual string value (note that it's outside the quotes). It's an indication that the string value is in the Unicode encoding. You want that!
This is actually not junk. The u before the string indicates that this is a unicode string. The \x1b[2J\x1b[1;1H is an escape sequence. I don't know exactly what it is supposed to do, but it appears to clear the screen when I print it out.
To see what I mean, try this code:
for string in output:
print string

How to run Ruby file on Sublime Text

I have a file named add_and_power.rb as below, and want to run it on Sublime Text.
def add_and_power a,b
(a+b)**(a+b)
end
puts "First number please? "
input1 = gets
puts "Second number please? "
input2 = gets
puts "The result is: ", add_and_power(input1.to_i, input2.to_i)
I run cmd+b, but it just displays,
First number please?
Second number please?
The result is:
1
[Finished in 0.9s]
I want to input 2 and 3 to get the answer. How can I make Sublime Text 2 ask for inputs and give back an answer?
If you want to run code within ST2, check out the SublimeREPL plugin, available through Package Control. You can either use IRB or pry, which is a lot more powerful. You can use it as a classic REPL (think Clojure or LISP), and you can also transfer your code from one tab into the running REPL in another tab by selection, line range, or block.
In some of my tests the pry REPL doesn't handle input through gets very well, but I haven't played around with it that much. YMMV - Edit - As AGS mentions below, use my_var = $stdin.gets for interactive input within SublimeREPL Ruby.
I highly highly recommend SublimeREPL, as it's a really powerful tool, and is self-contained within ST2, so you don't have to keep flipping back and forth to your terminal, saving and reloading your programs.
It is possible to run your programs when you need to have user input from the keyboard, but it isn't very nice.
When I do so, I need to input from a terminal that opens when I run Sublime, while also reading the response from the program at the bottom of the editor.
It is simply easier to run the program from the console/terminal.
So, the answer is, while it is possible to do so, there are concerns. You may need to use STDOUT.sync = true or STDOUT.flush to help manage the buffer with the OS, you have two thing to look at, while doing so... yuck.
It may not be the answer you are looking for, but as a developer, you should be comfortable running things from the console/terminal.

Get user input while still typing (in a terminal app)

I want to read user input from STDIN and process the preliminary input while the user is still typing.
A previous answer has some ruby code which enables this behaviour.
How to get a single character without pressing enter?
I would suggest reading something like http://ruby.runpaint.org/io
Call STDIN.getc to get individual characters that the user types.

How to use cbreak mode in Ruby terminal application?

In a small Ruby application, I'd like user input to be accepted without having to wait for a carriage return. My understanding is that cbreak mode needs to be enabled in order for the terminal to feed user input directly into the script.
I tried simply running x%[cbreak()] at the top of my script but that didn't work. I've also seen that it's possible to use (n)curses to achieve the same results, although that seems like overkill.
Does anybody have a suggestion on how to implement this?
Thanks
cbreak is a curses function call, so %x definitely doesn't apply (that is for executing shell commands). cbreak is defined in the standard curses library, so that would probably be your best bet.
See:
http://ruby-doc.org/stdlib/libdoc/curses/rdoc/classes/Curses.html#M000280
Edit: you might also check out Curses.getch
One solution which avoids having to use curses (which I find difficult to implement) is to use the shell's read command via %x. It doesn't feel right dipping into the shell to do something that seems like Ruby's STDIN should be responsible for, but it's simple and it works.
#! /usr/bin/ruby
puts "Please enter your first initial"
str = %x[read -s -n1 keypress; echo $keypress]
puts "Your first inital is " + str

How would one implement bash-like tab completion?

I'm trying to determine how the system prints characters to standard input -- that is, how it prints characters which the user can delete and which are considered input if the user hits "Enter."
I happen to be using C, but I would be very surprised if the solution were language-dependent.
Thanks for any insights! : D
As iny says, bash uses readline for its input. The source is available here, and there's a file called complete.c.
To answer your question, I don't think they're actually printed to standard input. Readline contains some kind of buffer for the contents of the line the user is editing, and completion prints into this. When the user presses enter, the contents of the buffer are sent to whatever program wanted to read a line, and in the case of bash, passed along into standard input. (Readline doesn't do this - other programs which use readline might simply store the value into a string for later use.)
Several people have pointed out that bash uses readline, which is true, but I think what you're really asking is how is it able to see what you've typed before you hit enter.
The answer is that ttys (ie: terminals) can be switched into "raw mode", where input processing of the terminal is disabled, and then you'll see every character as it comes in. This also disables automatic echoing of typed characters.
See this guide on Reading a single character from a file or a terminal for more info.
It uses readline library to handle the input and readline provides the history and the completion.
To actually implement completion, access to the keyboard input handling is needed. The completion must be able to modify the buffer used by it. After that it is just about looking at the current input and checking what completions is found. The actual completion logic can work in many ways.
Here's a C snippet that implements tab completion via readline:
http://github.com/rupa/el

Resources