10

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

3
  • You haven't shown what you tried, but I assume that you cannot simply call sudo as an NSTask, as it does very special things to authorize a user (including possible pop-up dialogs). Compare stackoverflow.com/questions/4050687/how-to-use-nstask-as-root. Commented Jul 2, 2015 at 19:16
  • thanks for your reply. I also added my current code to the question. Commented Jul 2, 2015 at 19:23
  • As I said, there are most probably general problems with your approach. Have a look at the linked-to thread. Commented Jul 2, 2015 at 19:26

1 Answer 1

8

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.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks Manav for your detailed answer. I used your solution and it improved my code a lot however I received the following output message: net.inet.tcp.delayed_ack: 3 sysctl: net.inet.tcp.delayed_ack=0: Operation not permitted
Are you sure your app isn't sandboxed? Also did you try my code as is or did you try with the bin/sh run path and the extra arguments? Also if you did the one with sudo are you sure you setup the pipe to the standardInput correctly and provided the root access password?
@ManavGabhawala the link is no longer active. Has your website moved?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.