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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31192722/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 07:24:45  来源:igfitidea点击:

Run a terminal command in a Mac app with Swift Xcode

xcodemacosswiftterminalnstask

提问by MRF

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

附注。这是我当前代码的样子(感谢您的回复):

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: Operation not allowed

采纳答案by Manav Gabhawala

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 NSTaskif 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.htmlwhich tells you about how to use sudo. For an unsandboxed app you could also do the same thing as above but change the launchPathto /bin/shand then add an argument "-S"and also add the argument "/usr/sbin/sysctl". Then you can use standardInputto 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 访问权限的用户的密码。所有密码输入错误都将出现在标准错误管道中。让我知道这个是否奏效。