5

I am trying to write a little MacRuby status bar application that runs a command from the command line and displays the output. I don't know how to do this. How can I do this from my Mac application?

Update: The other thing that it might need to do is ask for an administrator password. Sometimes when I run this script from the command line, it asks for my password. I don't know how I would prompt the user for their password (or embed the shell so they could type it directly).

Andrew
  • 227,796
  • 193
  • 515
  • 708

2 Answers2

6

Using Cocoa and MacRuby, utilize NSTask. Example that executes ls -la and prints output:

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

Unfortunately, including admin privileges is no trivial task, especially using MacRuby. Have a look at the SecurityFoundation framework, and this link. Essentially, you need to call

AuthorizationExecuteWithPrivileges(...)

with a configured AuthorizationRef, path of the tool to execute, flags, arguments. There is a useful example here (in ObjC) showing how this works.

jtomschroeder
  • 1,034
  • 7
  • 11
  • Thanks! That helps! From what I can tell, this will block until finished. Is there a way to asynchronously run the command and update the UI as each line is output? – Andrew Feb 16 '12 at 16:39
  • To update asynchronously, you can either use _readInBackgroundAndNotify_, or monitor StandardOutput in another thread. – jtomschroeder Feb 16 '12 at 18:02
1

You can simply use backticks:

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

If your command needs admin privileges to run, it won't run the command at all and won't return a response.

ghstcode
  • 2,902
  • 1
  • 20
  • 30
  • That looks like it might work, but I need to come up with a solution that allows me to prompt the user for password. When I run from the command line, sometimes, halfway through the script, it will try to do something that requires administrator privileges, so it will prompt the user for password. – Andrew Dec 19 '11 at 19:38
  • how about attempting to read a protected system file inside your objective-c main() method just before macruby_main(). That will force the authorization. – ghstcode Dec 19 '11 at 20:36