5

Suppose I have a string called very_long_string whose content I want to send to the standard output. But since the string is very long, I want to use less to display the text on the terminal. When I use

`less #{very_long_string}`

I get File not found error message, and if I use:

`less <<< #{very_long_string}`

I get unexpected redirection error message.

So, how to use less from inside Ruby?

Ankit
  • 423
  • 2
  • 12

3 Answers3

17

You could open a pipe and feed your string to less via its stdin.

IO.popen("less", "w") { |f| f.puts very_long_string }

(Assuming very_long_string is the variable holding your string.)

See: http://www.ruby-doc.org/core-1.8.7/IO.html#method-c-popen

user1252434
  • 2,083
  • 1
  • 15
  • 21
  • 2
    There is more to this than meets the eye. Two issues I have: 1) hitting 'q' to quit less produces an EPIPE error that results in a nasty looking stack being dumped out. That's easy to catch wit a rescue. 2) hitting ^C before all the output has been sent to less. less basically just eats the ^C. The ruby code does get an Interrupt but I can't figure out how to gracefully exit and still have less also exit gracefully and set the TTY back to their original settings. – pedz Nov 11 '16 at 17:15
1

Although less can read text files its natural fit is to use it as the last command in a pipe. So a natural fit would be:

shell-command-1 | shell-command-2 | shell-command-3 | less

At your shell prompt:

echo tanto va la gatta al lardo che ci lascia lo zampino|less

..So you can try this in irb:

`echo tanto va la gatta al lardo che ci lascia lo zampino|less`

but I will prefer to use:

your_string = "tanto va la gatta al lardo che ci lascia lo zampino"
`echo "#{your_string}"|less`

If you have time read this SO question.

For a thorough demonstration of using system calls in ruby see this gist: https://gist.github.com/4069

Community
  • 1
  • 1
microspino
  • 7,693
  • 3
  • 48
  • 49
  • I actually did use it, but nothing happened. No errors, no display nothing. The script simply returned. However, IO.popen() as suggested by @user1252434 worked very well. – Ankit Mar 09 '12 at 15:49
1

A simple hack:

require 'tempfile'
f = Tempfile.new('less')
f.write(long_string)

system("less #{f.path}")
Limbo Peng
  • 2,485
  • 19
  • 12