How to call shell commands from Ruby

前端 未结 20 2051
旧时难觅i
旧时难觅i 2020-11-22 01:10

How do I call shell commands from inside of a Ruby program? How do I then get output from these commands back into Ruby?

相关标签:
20条回答
  • 2020-11-22 01:52

    Some things to think about when choosing between these mechanisms are:

    1. Do you just want stdout or do you need stderr as well? Or even separated out?
    2. How big is your output? Do you want to hold the entire result in memory?
    3. Do you want to read some of your output while the subprocess is still running?
    4. Do you need result codes?
    5. Do you need a Ruby object that represents the process and lets you kill it on demand?

    You may need anything from simple backticks (``), system(), and IO.popen to full-blown Kernel.fork/Kernel.exec with IO.pipe and IO.select.

    You may also want to throw timeouts into the mix if a sub-process takes too long to execute.

    Unfortunately, it very much depends.

    0 讨论(0)
  • 2020-11-22 01:53

    The way I like to do this is using the %x literal, which makes it easy (and readable!) to use quotes in a command, like so:

    directorylist = %x[find . -name '*test.rb' | sort]
    

    Which, in this case, will populate file list with all test files under the current directory, which you can process as expected:

    directorylist.each do |filename|
      filename.chomp!
      # work with file
    end
    
    0 讨论(0)
  • 2020-11-22 01:53

    You can also use the backtick operators (`), similar to Perl:

    directoryListing = `ls /`
    puts directoryListing # prints the contents of the root directory
    

    Handy if you need something simple.

    Which method you want to use depends on exactly what you're trying to accomplish; check the docs for more details about the different methods.

    0 讨论(0)
  • 2020-11-22 01:59

    We can achieve it in multiple ways.

    Using Kernel#exec, nothing after this command is executed:

    exec('ls ~')
    

    Using backticks or %x

    `ls ~`
    => "Applications\nDesktop\nDocuments"
    %x(ls ~)
    => "Applications\nDesktop\nDocuments"
    

    Using Kernel#system command, returns true if successful, false if unsuccessful and returns nil if command execution fails:

    system('ls ~')
    => true
    
    0 讨论(0)
  • 2020-11-22 02:00

    My favourite is Open3

      require "open3"
    
      Open3.popen3('nroff -man') { |stdin, stdout, stderr| ... }
    
    0 讨论(0)
  • 2020-11-22 02:02

    I'm definitely not a Ruby expert, but I'll give it a shot:

    $ irb 
    system "echo Hi"
    Hi
    => true
    

    You should also be able to do things like:

    cmd = 'ls'
    system(cmd)
    
    0 讨论(0)
提交回复
热议问题