Cocoa中使用NSTask运行脚本

Cocoa中使用NSTask运行脚本

Cocoa编程中有时候会遇到需要运行一些脚本或者Shell命令的地方。这个时候,NSTask可能是一个不错的选择。

NSTask是MAC OS X用来执行系统命令的一个类库。

当然,也可以借助第三方封装的类库,比如:taskit

使用一个例子来知道怎么用:

场景是这样的:

假如,需要在程序内部嵌入一个nodejs工程,然后借助cocoa界面的一些操作是的外部与nodejs发生交互。

代码如下:

let task:NSTask! = NSTask();
let en:NSDictionary? = task.environment;
if en == nil {
    task.environment = ["PATH":"/usr/bin;/usr/local/bin/node;/usr/local/bin/thinkjs;/usr/local/bin/npm"];
}
print(task.environment);
task.launchPath = "/bin/bash";
task.arguments = ["-l","-c","cd /Users/Tywin/Desktop/DemoDir/; /bin/echo 1234;/usr/local/bin/thinkjs new app; cd /Users/Tywin/Desktop/DemoDir/app; /usr/local/bin/npm install;/usr/local/bin/thinkjs module Test; /usr/local/bin/npm start;"];
task.launch();
task.waitUntilExit();

首先,需要声明一个NSTask对象;

然后,如果需要用到除了系统之外的一些环境变量,需要为task对象设置环境变量,只有这样,才能完美运行后面的命令。

最后,设置launchPath,arguments,运行。


整个过程比较简单,shell命令那边就是打开一个文件夹,创建一个thinkjs的工程,运行工程依赖,然后使用npm start启动服务器。

这里需要注意的一个地方就是launchpath以及arguments里面的一些参数问题,发现在stackoverflow有个人是这样解释的,自我发觉解释的比较到位:

bash has three main modes of operation:

If you pass it -c “some command string”, it’ll execute that command string.
If you pass it a file path as an argument, it’ll read commands from that file and execute them (i.e. execute the file as a shell script).
If you don’t pass it any arguments, it’ll read and execute commands from standard input.
Since you passed it the arguments “/bin/echo” and “1234”, it’s assuming you want mode 2, so it tries to read shell commands from /bin/echo, and fails. I’m not clear on exactly what you’re trying to achieve, but I see several options that might be relevant:

If you’re trying to execute a binary (e.g. /bin/echo), just execute that directly without using bash at all:
task.launchPath = “/bin/echo”
task.arguments = [“1234”]
If you need to execute a command string (i.e. if you need the shell to parse it before executing it, so e.g. wildcards get expanded, or there’s more than one command, or…), use bash -c:
task.launchPath = “/bin/bash”
task.arguments = [“-c”, “/bin/echo 1234; ls *”]
If you need to execute an actual script, i.e. a file with shell commands in it, then leave runTask alone, but pass it an actual script:
runTask([“/path/to/script”, “scriptarg”, “another argument”])

坚持原创技术分享,您的支持将鼓励我继续创作!