【问题标题】:How to run shell commands from a Mac/MacRuby application?如何从 Mac/MacRuby 应用程序运行 shell 命令?
【发布时间】:2012-01-23 18:06:46
【问题描述】:

我正在尝试编写一个小的 MacRuby 状态栏应用程序,它从命令行运行命令并显示输出。我不知道该怎么做。如何从我的 Mac 应用程序中执行此操作?

更新:它可能需要做的另一件事是询问管理员密码。有时当我从命令行运行此脚本时,它会询问我的密码。我不知道如何提示用户输入密码(或嵌入 shell 以便他们直接输入)。

【问题讨论】:

  • 你的脚本到底是做什么的?
  • 最终,它将成为vagrant 的 GUI 包装器。所以我需要运行vagrant up 并查看输出。

标签: macos shell command-line macruby


【解决方案1】:

使用 Cocoa 和 MacRuby,利用 NSTask。执行 ls -la 并打印输出的示例:

framework 'Cocoa'

task = NSTask.alloc.init
task.setLaunchPath("/bin/ls")

arguments = NSArray.arrayWithObjects("-l", "-a", nil)
task.setArguments(arguments)

pipe = NSPipe.pipe
task.setStandardOutput(pipe)

file = pipe.fileHandleForReading

task.launch

data = file.readDataToEndOfFile

string = NSString.alloc.initWithData(data, encoding: NSUTF8StringEncoding)
puts "Command returned: "
puts string

不幸的是,包括管理员权限并非易事,尤其是在使用 MacRuby 时。看看 SecurityFoundation 框架和这个link。本质上,您需要调用

AuthorizationExecuteWithPrivileges(...)

带有已配置的 AuthorizationRef、要执行的工具的路径、标志、参数。有一个有用的示例 here(在 ObjC 中)展示了它是如何工作的。

【讨论】:

  • 谢谢!这有帮助!据我所知,这将阻塞直到完成。有没有办法在每行输出时异步运行命令并更新 UI?
  • 要异步更新,可以使用readInBackgroundAndNotify,或者在另一个线程中监控StandardOutput。
【解决方案2】:

你可以简单地使用反引号:

output = `cd ~ && ls`
puts output # or assign to a label, textbox etc.

如果您的命令需要管理员权限才能运行,它根本不会运行该命令并且不会返回响应。

【讨论】:

  • 看起来可能可行,但我需要想出一个解决方案,让我提示用户输入密码。当我从命令行运行时,有时,在脚本执行到一半的时候,它会尝试做一些需要管理员权限的事情,所以它会提示用户输入密码。
  • 在 macruby_main() 之前尝试在 Objective-c main() 方法中读取受保护的系统文件怎么样。这将强制授权。
猜你喜欢
  • 2018-06-24
  • 1970-01-01
  • 2018-03-10
  • 2011-07-18
  • 1970-01-01
  • 2016-12-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多