How to suppress Rails console/irb outputs
I was testing some DB entries in our produ开发者_如何学编程ction server in Rails Console where almost all the commands were producing a huge number of lines of output and causing the ssh channel to hang.
Is there a way to suppress the console/irb screenfuls?
You can append ; nil
to your statements.
Example:
users = User.all; nil
irb
prints the return value of the last executed statement; thus in this case it'll print only nil
since nil
is the last executed valid statement.
In search of a solution how to silence the irb/console output, I also found an answer at austinruby.com:
silence irb:
conf.return_format = ""
default output:
conf.return_format = "=> %s\n"
limit to eg 512 chars:
conf.return_format = "=> limited output\n %.512s\n"
running the following within irb works for me:
irb_context.echo = false
irb --simple-prompt --noecho
--simple-prompt
- Uses a simple prompt - just>>
--noecho
- Suppresses the result of operations
Here, add this to your ~/.irbrc:
require 'ctx'
require 'awesome_print'
module IRB
class Irb
ctx :ap do
def output_value()
ap(@context.last_value)
end
end
ctx :puts do
def output_value()
puts(@context.last_value)
end
end
ctx :p do
def output_value()
p(@context.last_value)
end
end
ctx :quiet do
def output_value()
end
end
end
end
def irb_mode(mode)
ctx(mode) { irb }
end
(Note: You must install the ctx
gem first, though awesome_print
is optional, of course.)
Now when you are on any console that uses irb, you can do the following:
Normal mode:
irb(main):001:0> { this:'is a complex object', that:[ { will:'probably'}, { be:'good to read' } ], in:{ some:{ formatted:'way'} } }
=> {:this=>"is a complex object", :that=>[{:will=>"probably"}, {:be=>"good to read"}], :in=>{:some=>{:formatted=>"way"}}}
...yep, just what you expect.
awesome_print
mode:
irb(main):002:0> irb_mode(:ap)
irb#1(main):001:0> { this:'is a complex object', that:[ { will:'probably'}, { be:'good to read' } ], in:{ some:{ formatted:'way'} } }
=> {
:this => "is a complex object",
:that => [
[0] {
:will => "probably"
},
[1] {
:be => "good to read"
}
],
:in => {
:some => {
:formatted => "way"
}
}
}
...wow, now everything is printing out awesomely! :)
Quiet mode:
irb#1(main):002:0> irb_mode(:quiet)
irb#1(main):001:0> { this:'is a complex object', that:[ { will:'probably'}, { be:'good to read' } ], in:{ some:{ formatted:'way'} } }
irb#1(main):002:0>
... whoah, no output at all? Nice.
Anyways, you can add whatever mode you like, and when you're finished with that mode, just exit
out or it, and you'll be back in the previous mode.
Hope that was helpful! :)
Supress Output, In General
Also, depending on your needs, have a look at using quietly
or silence_stream
for suppressing output in general, not just in the irb/console:
silence_stream(STDOUT) do
users = User.all
end
NOTE: silence_stream
removed in Rails 5+.
NOTE: quietly
will be deprecated in Ruby 2.2.0 and will eventually be removed. (Thanks BenMorganIO!)
More information can be found here.
Work Around for Rails 5+.
As mentioned above, silence_stream
is no longer available because it is not thread safe. There is no thread safe alternative. But if you still want to use silence_stream
and are aware that it is not thread safe and are not using it in a multithreaded manner, you can manually add it back as an initializer.
config/initializer/silence_stream.rb
# Re-implementation of `silence_stream` that was removed in Rails 5 due to it not being threadsafe.
# This is not threadsafe either so only use it in single threaded operations.
# See https://api.rubyonrails.org/v4.2.5/classes/Kernel.html#method-i-silence_stream.
#
def silence_stream( stream )
old_stream = stream.dup
stream.reopen( File::NULL )
stream.sync = true
yield
ensure
stream.reopen( old_stream )
old_stream.close
end
Adding nil
as a fake return value to silence output works fine, but I prefer to have some indication of what happened. A simple count is often enough. A lot of times, that's easily done by tacking on a count
function. So when I'm doing something to a bunch of Discourse topics, I don't want a printout of each of the topic objects. So I add .count
at the end of the loop:
Topic.where(...).each do |topic|
...
end.count
Same thing if I'm just assigning something:
(users = User.all).count
Silencing output altogether (or making it something static like nil
) deprives me of useful feedback.
精彩评论