我们时常会与操作系统交互或在 Ruby 中执行 Shell 命令。Ruby为我们提供了完成该任务的诸多方法。

  1. Exec

    Kernel#exec 通过执行给定的命令来替换当前进程,例如:

    $ irb
    >> exec 'echo "hello $HOSTNAME"'
    hello codefun
    $ 

    注意 exec 利用 echo 命令替换了 irb 进程,然后退出。因为 Ruby 实际上结束了该方法,所以只能有限使用。该方法的缺点是,你无法从 Ruby 脚本中知道命令是执行成功还是失败。

  2. System

    system 命令与 exec 操作相似,但它是在 subshell 中执行,而不是替换当前进程。与 exec 相比,system 给我们更多的信息。如果命令执行成功,它返回 true;否则返回 false。

    $irb
    >> system 'echo "hello $HOSTNAME"'
    hello codefun
    => true >> system 'false' => false >> puts $? 256 => nil >> 

    system 将进程的退出状态设置到全局变量 $?。注意 false 命令的退出状态,总是非 0 值。检查退出码让我们既可以抛出(raise)异常,又能够重试(retry)命令。

    新手注意:Unix 命令执行成功退出码为 0,否则为非 0。

    如果我们想知道“命令是否执行成功呢?”,使用 system 就很好。然而,我们时常想要捕获命令的输出,并在程序中使用。

  3. Backticks (`)

    backticks(也叫“backquotes”)在 subshell 中执行命令,并从该命令返回标准输出。

    $ irb
    >> today = `date`
    => "Wed Jul 4 22:03:15 CST 2012\n" >> $? => #<Process::Status: pid 6169 exit 0> >> $?.to_i => 0 

    这也许是在 subshell 中执行命令最广为人知的方法。如你所见,它返回了命令的输出,然后我们可以像其他字符串一样使用它。

    注意 $? 并非是返回状态的整数,而实际是 Process::Status 对象。我们不仅得到了退出状态,而且有进程 ID。Process::Status#to_i 返回整数型的退出状态(#to_s 返回字符串型的退出状态)。

    使用 backticks 我们只能获得命令的标准输出(stdout),而不能获得其标准错 误(stderr)。在下面的例子中,我们执行 Perl 脚本来输出字符串到标准错误。

    $ irb
    >> warning = `perl -e "warn 'dust in the wind'"`
    dust in the wind at -e line 1. => "" >> puts warning  => nil 

    注意变量 warning 没有被设置。当我们在 Perl 中执行 warn
    时,产生的标准错误输出并没有被 backticks 捕获。

  4. IO#popen

    IO#popen 是在子进程中执行命令的另一种方法。popen 给你更多的控制,子进程的标准输入和标准输出都会连接到 IO 对象。

    $ irb
    >> IO.popen("date") { |f| puts f.gets } Wed Jul 4 22:02:31 CST 2012 => nil 

    虽然 IO#popen 不错,但是当需要这类细分层次的信息时,我通常使用Open3#popen3

  5. Open3#popen3

    Ruby 标准库包含 Open3 类。它易用,并能返回标准输入、标准输出、以及标准 错误。在本例中,让我们使用交互命令 dc。dc 是从标准输入读取的逆波计算器(reverse-polish calculator)。我们先 push 两个数字和一个操作符到堆栈 中。然后我们使用 p 来打印输出结果。下面我们 push 5、10 及 +,结果标准输出获得了15。

    $ irb
    >> require 'open3'
    => true >> stdin, stdout, stderr = Open3.popen3('dc') => [#<IO:fd 6>, #<IO:fd 7>, #<IO:fd 9>, #<Thread:0x816d46c sleep>] >> stdin.puts(5) => nil >> stdin.puts(10) => nil >> stdin.puts("+") => nil >> stdin.puts("p") => nil >> stdout.gets => "15\n" 

    使用该命令我们不仅可以读取命令的输出,而且也能写到命令的标准输入。这允 许我们灵活地处理与命令的交互。

    如果我们需要,popen3 也将给我们标准错误。

    # (irb continued...)
    >> stdin.puts("asdfasdfasdfasdf")
    => nil >> stderr.gets => "dc: stack empty\n" 

    使用popen3 的缺点是 $? 不返回适当的退出状态。

    $ irb
    >> require 'open3'
    => true >> stdin, stdout, stderr = Open3.popen3('false') => [#<IO:fd 8>, #<IO:fd 10>, #<IO:fd 12>, #<Thread:0x8297644 sleep>] >> $? => nil >> $?.to_i => 0 

    0?false 是假定返回非 0 退出状态。该缺点带我们到 Open4。

  6. Open4#popen4

    Open4#popen4 是 Ara Howard 创建的 Ruby Gem。它的操作与 open3 相似,例外是我们能从程序获得退出状态。popen4 为 subshell 返回进程 ID,这样我们能从等候的进程获得退出状态。(你需要安装 open4 gem)

    $ irb
    >> require 'open4'
    => true >> pid, stdin, stdout, stderr = Open4::popen4 "false" => [17913, #<IO:fd 6>, #<IO:fd 7>, #<IO:fd 9>] >> $? => nil >> pid => 17913 >> ignored, status = Process::waitpid2 pid => [17913, #<Process::Status: pid 17913 exit 1>] >> status.to_i => 256 

    你也可以作为块来调用 popen4,它将自动等候退出状态。

    $ irb
    >> require 'open4'
    => true >> status = Open4::popen4("false") do |pid, stdin, stdout, stderr| ?> puts "PID #{pid}" >> end PID 18535 => #<Process::Status: pid 18535 exit 1> >> puts status pid 18535 exit 1 => nil 

原文来自 tech.natemurray.com
翻译 dailyrb
许可 CC-by-sa

转载于:https://www.cnblogs.com/heidsoft/p/4166031.html

在 Ruby 中执行 Shell 命令的 6 种方法相关推荐

  1. python调用shell命令-在Python中执行shell命令的6种方法,你都知道吗?

    原标题:在Python中执行shell命令的6种方法,你都知道吗? Python经常被称作"胶水语言",因为它能够轻易地操作其他程序,轻易地包装使用其他语言编写的库.今天我们就讲解 ...

  2. python调用shell命令-python中执行shell命令的几个方法小结

    最近有个需求就是页面上执行shell命令,第一想到的就是os.system, 复制代码 代码如下: os.system('cat /proc/cpuinfo') 但是发现页面上打印的命令执行结果 0或 ...

  3. Linux中执行shell脚本的4种方法

    这篇文章主要介绍了Linux中执行shell脚本的4种方法总结,即在Linux中运行shell脚本的4种方法,需要的朋友可以参考下. bash shell 脚本的方法有多种,现在作个小结.假设我们编写 ...

  4. python使用教程cmd啥意思-对python中执行DOS命令的3种方法总结

    1. 使用os.system("cmd") 特点是执行的时候程序会打出cmd在Linux上执行的信息. import os os.system("ls") 2. ...

  5. python运行命令_对python中执行DOS命令的3种方法总结

    1. 使用os.system("cmd") 特点是执行的时候程序会打出cmd在Linux上执行的信息. import os os.system("ls") 2. ...

  6. aix shell脚本 运行java_Linux中执行shell脚本的4种方法总结

    Linux中执行shell脚本的4种方法总结,即在Linux中运行shell脚本的4种方法: 方法一:切换到shell脚本所在的目录(此时,称为工作目录)执行shell脚本: 复制代码 代码如下: c ...

  7. Linux中执行shell脚本的5种方法总结

    Linux中执行shell脚本的4种方法总结,即在Linux中运行shell脚本的4种方法: 方法一:切换到shell脚本所在的目录(此时,称为工作目录)执行shell脚本: 复制代码 代码如下: c ...

  8. python运行方法_对python中执行DOS命令的3种方法总结

    1. 使用os.system("cmd") 特点是执行的时候程序会打出cmd在Linux上执行的信息. import os os.system("ls") 2. ...

  9. python中执行shell命令_python中执行shell命令的几个方法小结-阿里云开发者社区

    Python 执行 shell 命令 最近有个需求就是页面上执行shell命令,第一想到的就是os.system os.system('cat /proc/cpuinfo') 但是发现页面上打印的命令 ...

最新文章

  1. LeetCode刷题第二天——3Longest Substring Without repeating character 4 Median of Two Sorted Arrays...
  2. html美甲预约网页制作,教程.html · NFS1077/FNM美甲店 - Gitee.com
  3. python 写csv scrapy_Python神技能 | 使用爬虫获取汽车之家全车型数据
  4. html流星雨代码_HTML制作流星雨特效
  5. ddos攻击数据集_ddos攻击和cc攻击有什么区别?他们2个哪个更厉害?
  6. JS(JQuery)操作Array的相关方法
  7. 新浪新规:9点关灯,公司加班要交空调费:1600元/小时
  8. 御剑后台扫描工具下载
  9. 麒麟系统安装lnmp
  10. 中关村GHOST WIN7 SP1旗舰版
  11. while循环语法结构
  12. 关于Http的一些基础内容
  13. safari浏览器找不到服务器
  14. Opencv根据USB摄像头PID\VID号,获取对应摄像头索引
  15. matlab在线性系统中的应用,MATLAB在控制系统仿真中的应用
  16. kdj超卖_KDJ超卖区超买区是什么?有什么要注意的
  17. Microsoft Edge 和 Google Chrome更新后,出现错误代码:STATUS_STACK_BUFFER_OVERRUN,有效解决办法记录【已解决】
  18. 微信小程序低功耗蓝牙
  19. 计算机双代号网络图,双代号网络图计算机自动绘制研究.pdf
  20. 解决联想笔记本电脑经常突然休眠的问题

热门文章

  1. Android 安全架构及权限控制机制剖析
  2. Qt4: Show an image in your widget – 在Qt里面显示图像
  3. Oracle 存储方式大比拼
  4. Linux之ssh-agent命令
  5. Elasticsearch6.x和Kibana6.x的安装
  6. 两家美国科技公司被骗走一亿美元
  7. js Maximum call stack size exceeded
  8. 记一次DRBD Unknown故障处理过程
  9. 树的非递归(前序,中序,后序)
  10. c# lu分解的代码_LU分解(1)