【问题标题】:How do I write shell-like scripts using Ruby?如何使用 Ruby 编写类似 shell 的脚本?
【发布时间】:2013-06-08 14:24:48
【问题描述】:

我的任务是编写一个简单的 Ruby 脚本,它会执行以下操作。

在从 UNIX 命令行执行时,它会向用户显示一个提示,在该提示下他应该能够运行某些命令,例如“dir”、“help”或“exit”。在“exit”之后,用户应该返回到 Unix shell。

我不是在寻求解决方案;我只想知道如何在 Ruby 中实现这个“shell”功能。如何向用户提供提示和解释命令。

我不需要带有参数的 CLI 脚本。我需要一些可以创建 shell 接口的东西。

【问题讨论】:

  • ruby a.rb 工作得很好
  • @temuri,你有没有尝试过任何想法作为开始?例如,带有print "$ " 的基本循环(不是puts,因为它隐式添加了cr/lf)用于提示,gets 用于读取输入?然后,再次在基本级别上,对您从用户那里获取的字符串进行系统调用。在此基础上添加更多有趣的行为...

标签: ruby shell


【解决方案1】:

您需要的程序类型只需几个简单的结构即可轻松制作。 我知道你不是在寻求解决方案,但我只是给你一个框架,让你开始玩弄:

#!/usr/bin/env ruby
def prnthelp
  puts "Hello sir, what would you like to do?"
  puts "1: dir"
  puts "2: exit"
end

def loop
  prnthelp
  case gets.chomp.to_i
    when 1 then puts "you chose dir!"
    when 2 then puts "you chose exit!"
      exit
  end
  loop
end

loop

无论如何,这是一个关于如何做到这一点的简单示例,但可能 cmets 推荐的书更好。但这只是为了让你离开。

一些帮助您入门的命令是:

somevar = gets

这会获取用户输入。也许了解一些操作此输入的字符串方法可以为您带来一些好处。 http://ruby-doc.org/core-2.0/String.html chomp 将删除任何空格,to_i 将其转换为整数。

执行 Unix 的一些命令:

system('ls -la') #=> outputs the output of that command
exit #=> exits the program

无论如何,如果你想要这种东西,我认为查看http://www.codecademy.com/ 并不是一个坏主意,基本上他们通过编写诸如此类的小脚本来教你Ruby。但是,它们可能无法完全适应 Unix 命令,但肯定会处理用户输入等。


编辑:

正如所指出的,请在脚本的顶部使用它:

#!/usr/bin/env ruby

编辑:

chompchop 的示例:

full_name = "My Name is Ravikanth\r\n" 
full_name.chop! # => "My Name is Ravikanth"

现在如果你运行 chop 并且没有换行符:

puts full_name    #=> "My Name is Ravikanth"
full_name.chop!  #=> "My Name is Ravikant"

对比:

puts full_name       #=> "My Name is Ravikanth\r\n"

full_name.chomp!  #=> "My Name is Ravikanth"
full_name.chomp!  #=> "My Name is Ravikanth"

见:“Ruby Chop vs Chomp

【讨论】:

  • 'strip' 会更好吗?还要去掉前面的空白?
  • 使用chomp 而不是chop。第一种是手术切除尾随行尾。第二个是如果未找到行尾,则不加选择地删除字符串中的最后一个字符。 chop 也不会删除“空白”,它会删除“\r\n”。空白包含行尾、制表符、空格和换行符/垂直制表符。
  • strip 可能是。解析命令时通常不需要前导和尾随空格。另请查看squeeze(' ')
【解决方案2】:

这是一个非常基本的循环:

#!/user/bin/ruby
#
while true do
  print "$ "
  $stdout.flush
  inputs = gets.strip
  puts "got your input: #{inputs}"
  # Check for termination, like if they type in 'exit' or whatever...
  # Run "system" on inputs like 'dir' or whatever...
end

正如 Stefan 在评论中提到的那样,这是一个巨大的话题,并且有些场景会使事情变得复杂。正如我所说,这是一个非常基本的示例。

【讨论】:

  • 记住chompgets收到的输入。未能做到这一点是编写此类工具时非常痛苦的根源。
  • 好抓铁皮人。我更新并使用了“strip”来消除前后的空白。
【解决方案3】:

除了到目前为止发布的其他两个(有效)答案之外,请注意使用 #!/usr/bin/ruby,因为 ruby​​ 并不总是安装在那里。你可以改用这个:

#!/usr/bin/env ruby

或者如果你想要警告:

#!/usr/bin/env ruby -w

这样,无论您的服务器和笔记本电脑上安装 ruby​​ 的位置有何不同,您的脚本都能正常工作。

编辑:另外,请务必查看 Thor 和 Rake。

http://whatisthor.com

http://rake.rubyforge.org

【讨论】:

  • 我认为 Thor 或 Rake 不适合作为起点。它们面向命令行应用程序并执行系统配置和维护,这与 OP 的声明相反:I do not need a CLI script that takes arguments. I need something that creates a shell interface. 如果您可以展示一个简单的示例,它们将如何使用并且更有效,我认为您应该添加一个.
【解决方案4】:

使用irb。 我一直在寻找 bash 的替代方案,并按照相同的思路思考......但最终选择了 fishhttp://fishshell.com/

尽管如此,我正在考虑使用 irb 并按照 irbtools 的思路进行操作:https://github.com/janlelis/irbtools

例子:

> irb
Welcome to IRB. You are using ruby 1.9.3p0 (2011-10-30 revision 33570) [x86_64-linux]. Have fun ;)
>> ls #=> ["bin", "share", "opt", "lib", "var", "etc", "src"]
>>

无论如何,irb 是 ruby​​ shell。

【讨论】:

    【解决方案5】:

    看看cliqr,它内置了对构建自定义外壳的支持https://github.com/anshulverma/cliqr/

    【讨论】:

      猜你喜欢
      • 2010-09-15
      • 2011-06-24
      • 2019-11-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多