使用Swift Xcode在Mac应用程序中运行终端命令

时间:2021-01-02 20:21:34

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

我正在尝试在我正在开发的Mac应用程序中运行终端命令。终端命令是:

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.

我尝试过使用NSTask,但似乎每次我都做错了。

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):

PS。这是我当前的代码看起来像(感谢您的回复):

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

我在输出中收到以下消息:net.inet.tcp.delayed_ack:3 sysctl:net.inet.tcp.delayed_ack = 0:不允许操作

1 个解决方案

#1


5  

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

试试这个,让我知道它是否有效。您应该使用dispatch_async或NSOperationQueue在后台线程上执行此操作。有关如何使用Grand Central Dispatch执行操作的更多信息,请阅读我的帖子: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.

另外,如果这不起作用,请您更新问题以包括确切的错误以及您使用NSTask的代码。现在,如果你想看看,这将不会有你想要的sudo效果:https://developer.apple.com/library/mac/documentation/Security/Conceptual/authorization_concepts/01introduction/introduction.html它告诉你的如何使用sudo。对于未经过沙盒的应用程序,您也可以执行与上面相同的操作,但将launchPath更改为/ bin / sh,然后添加参数“-S”并添加参数“/ usr / sbin / sysctl”。然后,您可以使用standardInput来输入具有root访问权限的用户的密码。所有密码输入错误都将出现在标准错误管道中。让我知道这个是否奏效。

#1


5  

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

试试这个,让我知道它是否有效。您应该使用dispatch_async或NSOperationQueue在后台线程上执行此操作。有关如何使用Grand Central Dispatch执行操作的更多信息,请阅读我的帖子: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.

另外,如果这不起作用,请您更新问题以包括确切的错误以及您使用NSTask的代码。现在,如果你想看看,这将不会有你想要的sudo效果:https://developer.apple.com/library/mac/documentation/Security/Conceptual/authorization_concepts/01introduction/introduction.html它告诉你的如何使用sudo。对于未经过沙盒的应用程序,您也可以执行与上面相同的操作,但将launchPath更改为/ bin / sh,然后添加参数“-S”并添加参数“/ usr / sbin / sysctl”。然后,您可以使用standardInput来输入具有root访问权限的用户的密码。所有密码输入错误都将出现在标准错误管道中。让我知道这个是否奏效。