从Ruby运行一个shell脚本

4

我正在使用Frank进行iOS测试。它是一个使用Cucumber的Ruby gem。我有一个“Given”步骤,用于检测应用程序是否正在运行或是否已崩溃。如果我的步骤发现已经崩溃了,我想重新启动应用程序。我使用一个存储在靠近cucumber .feature文件的shell脚本来启动应用程序。

我如何从这个步骤定义中调用脚本?

4个回答

4
你可以用几种不同的方式实现这个。
Kernel.system "command"
%x[command]
`command`

顺便说一下,你不需要 Kernel. 这个模块;它已经默认包含在 Object 中了。或者类似的东西。 - Jwosty
2
是的,除非您有一个同名的本地方法,否则“Kernel”前缀是多余的,但是它对于查找文档很重要。那些无处不在的神奇方法通常在Kernel中。 - tadman
命名空间总是有好处的,正如@tadman所说的那样。 - Oliver Atkinson

2

正如其他答案所建议的那样,从Ruby执行shell脚本的方法有很多种,但它们并不都是一样的。我会尽力详细解释我所知道的所有方法。

反引号

`command arg1 arg2`
%x(command arg1 arg2)

运行命令并在子Shell中返回命令输出。将命令及其参数作为由反引号分隔的字符串提供。另一种语法是%x(...),用于避免转义问题,例如当您想要执行包含反引号本身的命令时。可以使用其他分隔符(如[]{}!!等)来替换括号,以便能够解决任何转义问题。

标准错误将按正常方式打印,标准输出将被抑制。返回命令的标准输出。这意味着您可以使用反引号符号将命令输出获取到一个变量中进一步处理。

Kernel.exec

exec("command arg1 arg2")
exec("command", "arg1", "arg2")

通过运行命令替换当前进程。命令及其参数可以作为普通字符串或逗号分隔的字符串列表提供。如果您已经有一个参数列表作为数组,这将非常有用。输出保持不变,即会像直接运行命令一样打印到控制台。

Kernel.system

system("command arg1 arg2")
system("command","arg1 arg2")

类似于 Kernel.exec,但是在子shell中运行。如果进程正确退出(状态为0),则返回true,否则返回false。这在if语句内部非常有效。

Kernel.spawn

pid = spawn("command")
# do other stuff
Process.wait(pid)

类似于Kernel.system,但会生成一个子进程来运行指定的命令。除非使用Process.wait,否则父进程不会等待命令执行完成。返回值为生成进程的PID。

IO.popen

io = IO.popen("command")
IO.popen("command") {|io| ... }

再次在子进程中运行命令,但允许更大的IO控制。子进程的stdout和stdin连接到一个IO对象,该对象可以作为返回值或块参数访问。如果通过返回值获取,使用io.close后应关闭IO对象。


1

Open3

如果您的使用场景比systemIO.popen更高级,您可以使用Ruby标准库中的Open3。它的popen3方法允许您手动与子进程的stdin、stdout和stderr进行交互。Open3的popen2方法相同,只是不提供stderr。下面是一个使用popen2的示例:

require 'open3'

Open3.popen2("wc -c") do |stdin, stdout, status_thread|
  stdin.print "answer to life the universe and everything"
  stdin.close
  p stdout.gets #=> "42\n"
end

-1

这里有一些不错的方法。反引号可能是最不具侵入性的方式。但要小心:正如tadman所指出的那样,exec会终止调用进程,这可以通过创建子进程或使用system来避免。


太棒了!你谷歌搜索到了。。 :) - Arup Rakshit
请记住,exec有效地终止了调用进程,因此您永远不会得到响应,所以它可能是该列表中的最后一个。 为什么它是最“可读”的? - tadman
我没有意识到它会这样做...就可读性而言,对于不熟悉Ruby的人来说,他们很快就能弄清楚它的作用,而不是反引号。 - Jwosty
他们无法理解的是,这将终止您的进程并永远不会返回任何内容,因此应该避免使用。反引号是Ruby与Perl共有的东西,因此这并不完全出乎意料。 - tadman
好的,我已经更新了答案以反映这些信息。感谢您的输入! :) - Jwosty

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接