2011-12-19 2 views
5

Я пытаюсь написать небольшое приложение строки состояния MacRuby, которое запускает команду из командной строки и отображает вывод. Я не знаю, как это сделать. Как я могу это сделать из своего приложения Mac?Как запустить команды оболочки из приложения Mac/MacRuby?

Обновление: Другое, что может потребоваться, это попросить пароль администратора. Иногда, когда я запускаю этот сценарий из командной строки, он запрашивает мой пароль. Я не знаю, как я попрошу пользователя ввести пароль (или встроить оболочку, чтобы они могли вводить ее напрямую).

+0

Что именно делает ваш сценарий? – SeanNieuwoudt

+0

В конце концов, это будет GUI-обертка для [бродяги] (http://vagrantup.com). Поэтому мне нужно будет запустить «vagrant up» и увидеть результат. – Andrew

ответ

6

Используя 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), показывающий, как это работает.

+0

Обновленный ответ. – jtomschroeder

+0

Спасибо! Что помогает! Из того, что я могу сказать, это будет заблокировано до конца. Есть ли способ асинхронно запускать команду и обновлять пользовательский интерфейс при выходе каждой строки? – Andrew

+0

Чтобы обновить асинхронно, вы можете использовать _readInBackgroundAndNotify_ или контролировать StandardOutput в другом потоке. – jtomschroeder

1

Вы можете просто использовать кавычку:

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

Если ваша команда нуждается права администратора для запуска, он не будет запускать команду на всех и не будет возвращать ответ.

+0

Похоже, что это может сработать, но мне нужно придумать решение, которое позволяет мне запрашивать у пользователя пароль. Когда я запускаю из командной строки, иногда, наполовину через скрипт, он попытается сделать что-то, что требует прав администратора, поэтому он будет запрашивать у пользователя пароль. – Andrew

+0

как насчет попытки прочитать защищенный системный файл внутри вашего метода object-c main() непосредственно перед macruby_main(). Это приведет к авторизации. – SeanNieuwoudt