Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 在'irb'中,backticks抛出异常,但在'rails c'中,它们不';T 操作系统:Debian GNU/Linux 8 Ruby版本:2.4.1 Rails版本:5.1.4_Ruby On Rails_Ruby_Shell_Backticks - Fatal编程技术网

Ruby on rails 在'irb'中,backticks抛出异常,但在'rails c'中,它们不';T 操作系统:Debian GNU/Linux 8 Ruby版本:2.4.1 Rails版本:5.1.4

Ruby on rails 在'irb'中,backticks抛出异常,但在'rails c'中,它们不';T 操作系统:Debian GNU/Linux 8 Ruby版本:2.4.1 Rails版本:5.1.4,ruby-on-rails,ruby,shell,backticks,Ruby On Rails,Ruby,Shell,Backticks,我刚刚使用了railsnew创建了一个全新的rails项目。在它的目录中,我使用irb,尝试对不存在的可执行文件执行shell命令,并引发异常: irb(main):001:0> `foobar` Errno::ENOENT: No such file or directory - foobar from (irb):1:in ``' from (irb):1 from /home/jackson/.rbenv/versions/2.4.1/bin/irb:11:i

我刚刚使用了
railsnew
创建了一个全新的rails项目。在它的目录中,我使用
irb
,尝试对不存在的可执行文件执行shell命令,并引发异常:

irb(main):001:0> `foobar`
Errno::ENOENT: No such file or directory - foobar
    from (irb):1:in ``'
    from (irb):1
    from /home/jackson/.rbenv/versions/2.4.1/bin/irb:11:in `<top (required)>'
    from /home/jackson/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/bundler-1.14.6/lib/bundler/cli/exec.rb:74:in `load'
    from /home/jackson/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/bundler-1.14.6/lib/bundler/cli/exec.rb:74:in `kernel_load'
    from /home/jackson/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/bundler-1.14.6/lib/bundler/cli/exec.rb:27:in `run'
    from /home/jackson/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/bundler-1.14.6/lib/bundler/cli.rb:335:in `exec'
    from /home/jackson/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/bundler-1.14.6/lib/bundler/vendor/thor/lib/thor/command.rb:27:in `run'
    from /home/jackson/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/bundler-1.14.6/lib/bundler/vendor/thor/lib/thor/invocation.rb:126:in `invoke_command'
    from /home/jackson/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/bundler-1.14.6/lib/bundler/vendor/thor/lib/thor.rb:359:in `dispatch'
    from /home/jackson/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/bundler-1.14.6/lib/bundler/cli.rb:20:in `dispatch'
    from /home/jackson/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/bundler-1.14.6/lib/bundler/vendor/thor/lib/thor/base.rb:440:in `start'
    from /home/jackson/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/bundler-1.14.6/lib/bundler/cli.rb:11:in `start'
    from /home/jackson/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/bundler-1.14.6/exe/bundle:32:in `block in <top (required)>'
    from /home/jackson/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/bundler-1.14.6/lib/bundler/friendly_errors.rb:121:in `with_friendly_errors'
    from /home/jackson/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/bundler-1.14.6/exe/bundle:24:in `<top (required)>'
    from /home/jackson/.rbenv/versions/2.4.1/bin/bundle:22:in `load'
    from /home/jackson/.rbenv/versions/2.4.1/bin/bundle:22:in `<main>'
这种不一致性似乎反映在Rails控制台之外。在我的Rails应用程序中,Backticks还返回
nil
。这是一个问题,因为我们的一个gem中缺少命令的错误处理被破坏,因为它没有引发异常:


这种行为差异是故意的吗?如果没有,有什么问题,我该如何解决这个问题?

您的问题似乎是Rails试图标准化行为:

class Object
  # Makes backticks behave (somewhat more) similarly on all platforms.
  # On win32 `nonexistent_command` raises Errno::ENOENT; on Unix, the
  # spawned shell prints a message to stderr and sets $?. We emulate
  # Unix on the former but not the latter.
  def `(command) #:nodoc:
    super
  rescue Errno::ENOENT => e
    STDERR.puts "#$0: #{e}"
  end
end
到处都是责怪:

  • 用于替换核心方法的Rails
  • 使用backticks而不是像
    Open3
    这样更安全、更干净的东西的gem
  • Ruby没有指定
    Kernel#`
    的行为方式(如果你足够自以为是的话,甚至可能会有反勾号)
这是有办法的。您可以尝试删除初始值设定项中的ActiveSupport覆盖:

Object.send(:remove_method, :'`')
因此,将使用
内核
中的标准反勾号。或者,如果您从未期望使用
lt
命令,则可以替换gem的方法:

module LocalTunnel
  class Client
    def self.package_installed?
      false
    end
  end
end
或者用您自己的实现替换
LocalTunnel::Client.package\u installed?
,该实现通过检查backticks可能失败的各种方式,或者使用
Open3
中的方法而不是backticks,围绕Rails覆盖工作。您还可以通过分解
PATH
环境变量(使用
File::PATH_SEPARATOR
)和
File.executable?
手动查找
lv


您使用哪一个kludge取决于您有什么可移植性要求,以及什么在您的环境中起作用。

在我看来,从现在开始,我应该把backticks扔进垃圾箱。你有没有建议我通常如何用“更安全、更干净的东西,比如
Open3
”,最好是用一个同步代码示例来替换backticks?我倾向于远离backticks,即
system
的单参数版本,以及任何其他将调用shell的东西,太脆弱,容易出错,无法正确使用。您可能会使用
Open3.capture2('some_命令','-arg')
而不是
%x{some_命令-arg}
)。
module LocalTunnel
  class Client
    def self.package_installed?
      false
    end
  end
end