2015-07-02 13 views
5

Sto provando a eseguire un comando di terminale in un'app per Mac che sto sviluppando. Il comando da terminale è:Esegui un comando di terminale in un'app Mac con Swift Xcode

sudo sysctl -w net.inet.tcp.delayed_ack=0 

Ho provato con NSTask ma sembra che sto facendo qualcosa di sbagliato ogni volta.

Voglio solo eseguire questo comando e stampare l'output. Grazie per l'attenzione.

PS. qui è ciò che il mio codice attuale assomiglia (grazie alle vostre risposte):

let task = NSTask() 
task.launchPath = "/usr/sbin/sysctl" 
task.arguments = ["-w", "net.inet.tcp.delayed_ack=0"] 
let pipe = NSPipe() 
task.standardOutput = pipe 
task.standardError = pipe 
task.launch() 
task.waitUntilExit() 
let data = pipe.fileHandleForReading.readDataToEndOfFile() 
let output: String = NSString(data: data, encoding: NSUTF8StringEncoding) as! String 

ricevo il seguente messaggio nell'output:
net.inet.tcp.delayed_ack: 3
sysctl: net.inet. tcp.delayed_ack = 0: Operazione non consentita

+0

Non hai mostrato ciò che hai provato, ma presumo che tu non possa semplicemente chiamare sudo come un NSTask, dato che fa cose molto speciali per autorizzare un utente (comprese le possibili finestre di dialogo a comparsa). Confronta http://stackoverflow.com/questions/4050687/how-to-use-nstask-as-root. –

+0

grazie per la tua risposta. Ho anche aggiunto il mio codice attuale alla domanda. – MRF

+0

Come ho già detto, ci sono probabilmente problemi generali con il tuo approccio. Dai un'occhiata alla discussione collegata. –

risposta

5

Prova questo e fammi sapere se funziona. Dovresti farlo su un thread in background usando dispatch_async o NSOperationQueue. Per ulteriori informazioni su come fare cose con Grand Central Dispatch leggere il mio post: http://manavgabhawala.me/#/blog/grand-central-dispatch

let task = NSTask() 
task.launchPath = "/usr/sbin/sysctl" 
task.arguments = ["-w", "net.inet.tcp.delayed_ack=0"] 
let pipe = NSPipe() 
task.standardOutput = pipe 
task.standardError = pipe 
task.launch() 
task.waitUntilExit() 
let data = pipe.fileHandleForReading.readDataToEndOfFile() 
let output: String = NSString(data: data, encoding: NSUTF8StringEncoding) as! String 

Inoltre si prega si può aggiornare la domanda per includere l'errore esatto e il codice che si sta utilizzando con NSTask se questo non funziona . Ora questo non avrà l'effetto sudo che volevi se volessi dare un'occhiata a: https://developer.apple.com/library/mac/documentation/Security/Conceptual/authorization_concepts/01introduction/introduction.html che ti dice come usare sudo. Per un'app non memorizzata puoi anche fare la stessa cosa come sopra ma modificare lo launchPath in /bin/sh e aggiungere un argomento "-S" e aggiungere anche l'argomento "/usr/sbin/sysctl". Quindi è possibile utilizzare standardInput per reindirizzare la password dell'utente con accesso root. Tutti gli errori di immissione della password arriveranno nella pipe error standard. Fammi sapere se funziona.

+0

Grazie Manav per la tua risposta dettagliata. Ho usato la tua soluzione e ha migliorato molto il mio codice ma ho ricevuto il seguente messaggio di output: net.inet.tcp.delayed_ack: 3 sysctl: net.inet.tcp.delayed_ack = 0: Operazione non consentita – MRF

+0

Sei sicuro la tua app non è in modalità sandbox? Inoltre hai provato il mio codice così com'è o hai provato con il percorso di esecuzione bin/sh e gli argomenti extra? Inoltre, se hai fatto quello con sudo, sei sicuro di aver impostato correttamente la pipe su standardInput e hai fornito la password di accesso root? –

+0

@ManavGabhawala il link non è più attivo. Il tuo sito web è stato spostato? –