当 运行 Sinatra 在已占用的端口上时避免显示回溯
Avoid display of backtrace when running Sinatra on an already taken port
当 Sinatra 无法正确 运行 服务器(例如,由于端口已被使用)时,阻止 Sinatra 显示完整回溯的正确方法是什么?
这是一个示例 sinatra 应用程序:
# test.rb
require 'sinatra'
require 'bundler/inline'
gemfile do
gem 'sinatra'
gem 'puma'
end
set :bind, "0.0.0.0"
set :port, 3000
get '/' do
"hello"
end
然后运行与ruby test.rb
连接一次,占用端口
然后,运行在另一个终端中再次使用它 window,并显示完整的错误回溯:
$ ruby test.rb
== Sinatra (v2.0.4) has taken the stage on 3000 for development with backup from Puma
Puma starting in single mode...
* Version 3.12.0 (ruby 2.5.0-p0), codename: Llamas in Pajamas
* Min threads: 0, max threads: 16
* Environment: development
* Listening on tcp://0.0.0.0:3000
== Someone is already performing on port 3000!
Traceback (most recent call last):
5: from /store/gems/ruby-2.5.0/gems/sinatra-2.0.4/lib/sinatra/main.rb:26:in `block in <module:Sinatra>'
4: from /store/gems/ruby-2.5.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:1464:in `run!'
3: from /store/gems/ruby-2.5.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:1464:in `ensure in run!'
2: from /store/gems/ruby-2.5.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:1439:in `quit!'
1: from /store/gems/ruby-2.5.0/gems/puma-3.12.0/lib/puma/launcher.rb:147:in `stop'
/store/gems/ruby-2.5.0/gems/puma-3.12.0/lib/puma/single.rb:27:in `stop': undefined method `stop' for nil:NilClass (NoMethodError)
Traceback (most recent call last):
3: from /store/gems/ruby-2.5.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:1545:in `block in setup_traps'
2: from /store/gems/ruby-2.5.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:1439:in `quit!'
1: from /store/gems/ruby-2.5.0/gems/puma-3.12.0/lib/puma/launcher.rb:147:in `stop'
/store/gems/ruby-2.5.0/gems/puma-3.12.0/lib/puma/single.rb:27:in `stop': undefined method `stop' for nil:NilClass (NoMethodError)
因为我将它用作嵌入式服务器,所以我希望输出简单并且带有 Sinatra 已经显示的友好错误:
== Someone is already performing on port 3000!
并避免显示回溯。
Ruby 默认输出错误信息到 STDOUT。但是如果你在 *nix 系统上,你可以这样做:
ruby test.rb > /dev/null 2>&1
对于windows你大概可以做到
ruby test.rb > NULL
windows powershell
ruby test.rb > $null
但对于 windows 另见 Is there a /dev/null on Windows?
但是如果你想在服务器为 运行 时以编程方式抑制输出,这应该适用于 *nix 但不确定 windows
# test.rb
require 'sinatra'
require 'bundler/inline'
gemfile do
gem 'sinatra'
gem 'puma'
end
set :bind, "0.0.0.0"
set :port, 3000
get '/' do
"hello"
end
unless `ps aux | grep sinatra`.match('tcp://0.0.0.0:3000')
STDOUT.reopen('/dev/null', 'w')
STDERR.reopen('/dev/null', 'w')
end
见suppresing output to console with ruby
您可以通过在允许 Sinatra 和 Puma 接管之前尝试侦听端口来测试端口是否正在使用。这不是 100% 有效,因为存在竞争条件,您可以打开和关闭端口,但在 Sinatra/Puma 完成初始化之前,一些其他进程出现并侦听同一端口,但它应该适合您使用 -案例(这似乎只是一个装饰黑客)。
在 test.rb
中的任意位置插入此代码:
require 'socket'
include Socket::Constants
begin
# Open and close the port
socket = Socket.new(AF_INET, SOCK_STREAM, 0)
sockaddr = Socket.pack_sockaddr_in(3000, '0.0.0.0')
socket.bind(sockaddr)
socket.listen(1)
socket.close
rescue Errno::EADDRINUSE => error
# Traps the same error that is trapped by Sinatra and exits if raised
puts error.message
exit
end
第一个开始 ruby test.rb
:
== Sinatra (v2.0.4) has taken the stage on 3000 for development with backup from Puma
Puma starting in single mode...
* Version 3.12.0 (ruby 2.6.0-p-1), codename: Llamas in Pajamas
* Min threads: 0, max threads: 16
* Environment: development
* Listening on tcp://0.0.0.0:3000
Use Ctrl-C to stop
第二个开始 ruby test.rb
:
Address already in use - bind(2) for 0.0.0.0:3000
您可以在 rescue
块内充实您想要打印到控制台的内容。
这似乎是由 issue with Puma, that is fixed by this PR 引起的。
当 Sinatra 无法正确 运行 服务器(例如,由于端口已被使用)时,阻止 Sinatra 显示完整回溯的正确方法是什么?
这是一个示例 sinatra 应用程序:
# test.rb
require 'sinatra'
require 'bundler/inline'
gemfile do
gem 'sinatra'
gem 'puma'
end
set :bind, "0.0.0.0"
set :port, 3000
get '/' do
"hello"
end
然后运行与ruby test.rb
连接一次,占用端口
然后,运行在另一个终端中再次使用它 window,并显示完整的错误回溯:
$ ruby test.rb
== Sinatra (v2.0.4) has taken the stage on 3000 for development with backup from Puma
Puma starting in single mode...
* Version 3.12.0 (ruby 2.5.0-p0), codename: Llamas in Pajamas
* Min threads: 0, max threads: 16
* Environment: development
* Listening on tcp://0.0.0.0:3000
== Someone is already performing on port 3000!
Traceback (most recent call last):
5: from /store/gems/ruby-2.5.0/gems/sinatra-2.0.4/lib/sinatra/main.rb:26:in `block in <module:Sinatra>'
4: from /store/gems/ruby-2.5.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:1464:in `run!'
3: from /store/gems/ruby-2.5.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:1464:in `ensure in run!'
2: from /store/gems/ruby-2.5.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:1439:in `quit!'
1: from /store/gems/ruby-2.5.0/gems/puma-3.12.0/lib/puma/launcher.rb:147:in `stop'
/store/gems/ruby-2.5.0/gems/puma-3.12.0/lib/puma/single.rb:27:in `stop': undefined method `stop' for nil:NilClass (NoMethodError)
Traceback (most recent call last):
3: from /store/gems/ruby-2.5.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:1545:in `block in setup_traps'
2: from /store/gems/ruby-2.5.0/gems/sinatra-2.0.4/lib/sinatra/base.rb:1439:in `quit!'
1: from /store/gems/ruby-2.5.0/gems/puma-3.12.0/lib/puma/launcher.rb:147:in `stop'
/store/gems/ruby-2.5.0/gems/puma-3.12.0/lib/puma/single.rb:27:in `stop': undefined method `stop' for nil:NilClass (NoMethodError)
因为我将它用作嵌入式服务器,所以我希望输出简单并且带有 Sinatra 已经显示的友好错误:
== Someone is already performing on port 3000!
并避免显示回溯。
Ruby 默认输出错误信息到 STDOUT。但是如果你在 *nix 系统上,你可以这样做:
ruby test.rb > /dev/null 2>&1
对于windows你大概可以做到
ruby test.rb > NULL
windows powershell
ruby test.rb > $null
但对于 windows 另见 Is there a /dev/null on Windows?
但是如果你想在服务器为 运行 时以编程方式抑制输出,这应该适用于 *nix 但不确定 windows
# test.rb
require 'sinatra'
require 'bundler/inline'
gemfile do
gem 'sinatra'
gem 'puma'
end
set :bind, "0.0.0.0"
set :port, 3000
get '/' do
"hello"
end
unless `ps aux | grep sinatra`.match('tcp://0.0.0.0:3000')
STDOUT.reopen('/dev/null', 'w')
STDERR.reopen('/dev/null', 'w')
end
见suppresing output to console with ruby
您可以通过在允许 Sinatra 和 Puma 接管之前尝试侦听端口来测试端口是否正在使用。这不是 100% 有效,因为存在竞争条件,您可以打开和关闭端口,但在 Sinatra/Puma 完成初始化之前,一些其他进程出现并侦听同一端口,但它应该适合您使用 -案例(这似乎只是一个装饰黑客)。
在 test.rb
中的任意位置插入此代码:
require 'socket'
include Socket::Constants
begin
# Open and close the port
socket = Socket.new(AF_INET, SOCK_STREAM, 0)
sockaddr = Socket.pack_sockaddr_in(3000, '0.0.0.0')
socket.bind(sockaddr)
socket.listen(1)
socket.close
rescue Errno::EADDRINUSE => error
# Traps the same error that is trapped by Sinatra and exits if raised
puts error.message
exit
end
第一个开始 ruby test.rb
:
== Sinatra (v2.0.4) has taken the stage on 3000 for development with backup from Puma
Puma starting in single mode...
* Version 3.12.0 (ruby 2.6.0-p-1), codename: Llamas in Pajamas
* Min threads: 0, max threads: 16
* Environment: development
* Listening on tcp://0.0.0.0:3000
Use Ctrl-C to stop
第二个开始 ruby test.rb
:
Address already in use - bind(2) for 0.0.0.0:3000
您可以在 rescue
块内充实您想要打印到控制台的内容。
这似乎是由 issue with Puma, that is fixed by this PR 引起的。