我正在使用 Frank 进行 iOS 测试。它也是一种使用黄瓜的红宝石。我有一个“给定”步骤来检查应用程序是否正在运行或是否已崩溃。如果我的步骤发现它已经崩溃,我想再次启动该应用程序。我使用存储在黄瓜 .feature 文件附近某处的 shell 脚本启动应用程序。
如何从该步骤定义中调用脚本?
你可以通过几种不同的方式做到这一点
Kernel.system "command"
%x[command]
`command`
正如其他答案所建议的那样,有很多方法可以从 Ruby 执行 shell 脚本,但它们的创建方式并不相同。我将尝试更详细地解释我知道的所有方法。
`command arg1 arg2`
%x(command arg1 arg2)
在子 shell 中运行命令并返回命令的输出。命令及其参数以反引号分隔的字符串形式提供。另一种语法%x(...)
用于避免转义问题,例如,当您要执行包含反引号的命令时。括号可以替换为其他分隔符,例如[]
, {}
, !!
, ... 以便能够解决任何转义问题。
Stderr 正常打印,Stdout 被抑制。返回命令的标准输出。这意味着您可以使用反引号将命令的输出放入变量中以进行进一步处理。
exec("command arg1 arg2")
exec("command", "arg1", "arg2")
通过运行命令替换当前进程。命令及其参数以普通字符串或以逗号分隔的字符串列表的形式提供。如果您已经有一个参数列表作为数组,这可能会很有用。输出保持原样,即像直接运行命令一样打印到控制台。
system("command arg1 arg2")
system("command","arg1 arg2")
像Kernel.exec
但再次在子shell中运行。true
如果进程正确退出(状态 0)则返回,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对象在使用后需要关闭io.close
。
system
对于比or更高级的用例IO.popen
,您可以使用Ruby 标准库中的Open3。它的popen3
方法允许您手动与子进程的标准输入、标准输出和标准错误进行交互。Open3 的popen2
方法是一样的,只是它没有给你标准错误。使用示例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
.