Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Run a terminal command in a Mac app with Swift Xcode

I am trying to run a terminal command in a Mac app that I am developing. The terminal command is:

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

I have tried using NSTask but it seems that I am doing something wrong every time.

I just want to run this command and print the output. Thank you for your attention.

PS. here is what my current code looks like (thanks to your replies):

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

I receive the following message in the output:
net.inet.tcp.delayed_ack: 3
sysctl: net.inet.tcp.delayed_ack=0: Operation not permitted

like image 379
MRF Avatar asked Jul 02 '15 19:07

MRF


People also ask

How do I run a Terminal command on a Mac?

In the Terminal app on your Mac, press the Up Arrow key. The last command you entered appears on the command line. Continue pressing the Up Arrow key until you see the command you want, then press Return.

Can you use Swift in Terminal?

Swift commands are a powerful and lightweight way to compile and run Swift code from the terminal. They're handy when we're verifying concepts and even when we're developing projects.

Can Swift be used for macOS apps?

Swift is available on macOS, Linux, and Windows. This means that you can create Swift applications on these platforms. You don't need a Mac to learn Swift. If you want to build and shipt applications for iOS (and iPadOS), tvOS, macOS, or watchOS, then you need Xcode.


1 Answers

Try this and let me know if it works. You should do this on a background thread using dispatch_async or NSOperationQueue. For more information on how to do stuff using Grand Central Dispatch read my 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

Also please can you update the question to include the exact error and the code you are using with NSTask if this doesn't work. Now this won't have the sudo effect that you wanted if you want that look at: https://developer.apple.com/library/mac/documentation/Security/Conceptual/authorization_concepts/01introduction/introduction.html which tells you about how to use sudo. For an unsandboxed app you could also do the same thing as above but change the launchPath to /bin/sh and then add an argument "-S" and also add the argument "/usr/sbin/sysctl". Then you can use standardInput to pipe in the password of the user who has root access. All password entry errors will come in the standard error pipe. Let me know if this works.

like image 195
Manav Gabhawala Avatar answered Nov 15 '22 20:11

Manav Gabhawala