我正在使用Frank进行iOS测试。它是一个使用Cucumber的Ruby gem。我有一个“Given”步骤,用于检测应用程序是否正在运行或是否已崩溃。如果我的步骤发现已经崩溃了,我想重新启动应用程序。我使用一个存储在靠近cucumber .feature文件的shell脚本来启动应用程序。
我如何从这个步骤定义中调用脚本?
Kernel.system "command"
%x[command]
`command`
正如其他答案所建议的那样,从Ruby执行shell脚本的方法有很多种,但它们并不都是一样的。我会尽力详细解释我所知道的所有方法。
`command arg1 arg2`
%x(command arg1 arg2)
运行命令并在子Shell中返回命令输出。将命令及其参数作为由反引号分隔的字符串提供。另一种语法是%x(...)
,用于避免转义问题,例如当您想要执行包含反引号本身的命令时。可以使用其他分隔符(如[]
、{}
、!!
等)来替换括号,以便能够解决任何转义问题。
标准错误将按正常方式打印,标准输出将被抑制。返回命令的标准输出。这意味着您可以使用反引号符号将命令输出获取到一个变量中进一步处理。
exec("command arg1 arg2")
exec("command", "arg1", "arg2")
通过运行命令替换当前进程。命令及其参数可以作为普通字符串或逗号分隔的字符串列表提供。如果您已经有一个参数列表作为数组,这将非常有用。输出保持不变,即会像直接运行命令一样打印到控制台。
system("command arg1 arg2")
system("command","arg1 arg2")
类似于 Kernel.exec
,但是在子shell中运行。如果进程正确退出(状态为0),则返回true
,否则返回false
。这在if
语句内部非常有效。
pid = spawn("command")
# do other stuff
Process.wait(pid)
类似于Kernel.system
,但会生成一个子进程来运行指定的命令。除非使用Process.wait
,否则父进程不会等待命令执行完成。返回值为生成进程的PID。
io = IO.popen("command")
IO.popen("command") {|io| ... }
再次在子进程中运行命令,但允许更大的IO控制。子进程的stdout和stdin连接到一个IO对象,该对象可以作为返回值或块参数访问。如果通过返回值获取,使用io.close
后应关闭IO对象。
如果您的使用场景比system
或IO.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
这里有一些不错的方法。反引号可能是最不具侵入性的方式。但要小心:正如tadman所指出的那样,exec
会终止调用进程,这可以通过创建子进程或使用system
来避免。
Kernel.
这个模块;它已经默认包含在 Object 中了。或者类似的东西。 - Jwosty