- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想用 NSTask 来模拟 Terminal 来运行命令。代码如下。它可以循环获取输入并返回过程输出。
int main(int argc, const char * argv[])
{
@autoreleasepool {
while (1) {
char str[80] = {0};
scanf("%s", str);
NSString *cmdstr = [NSString stringWithUTF8String:str];
NSTask *task = [NSTask new];
[task setLaunchPath:@"/bin/sh"];
[task setArguments:[NSArray arrayWithObjects:@"-c", cmdstr, nil]];
NSPipe *pipe = [NSPipe pipe];
[task setStandardOutput:pipe];
[task launch];
NSData *data = [[pipe fileHandleForReading] readDataToEndOfFile];
[task waitUntilExit];
NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"%@", string);
}
}
我的问题是:当一个循环结束后,运行环境恢复到初始化状态。比如默认的运行路径是/Users/apple
,我运行cd/
把路径改成/
,然后运行pwd
,它返回/Users/apple
而不是/
。
那么如何使用 NSTask
来完全模拟终端呢?
最佳答案
cd
和 pwd
是 shell 内置命令。如果执行任务
/bin/sh -c "cd /"
无法将更改后的工作目录返回给调用进程。如果要设置变量 MYVAR=myvalue
,也会存在同样的问题。
您可以尝试分别解析这些行并更新环境。但是像
这样的多行命令呢?for file in *.txt
do
echo $file
done
您不能通过将每一行发送到单独的 NSTask
进程来模拟它。
你唯一能做的就是用 NSTask
启动一个单个 /bin/sh
进程,并将所有输入行提供给该过程的标准输入。但是你不能使用 readDataToEndOfFile
来读取输出,但你必须异步读取(使用 [[pipe fileHandleForReading] waitForDataInBackgroundAndNotify]
)。
简而言之:您只能通过运行(单个)shell 来模拟终端。
已添加:或许您可以将以下内容作为您应用的起点。 (我省略了所有错误检查。)
int main(int argc, const char * argv[])
{
@autoreleasepool {
// Commands are read from standard input:
NSFileHandle *input = [NSFileHandle fileHandleWithStandardInput];
NSPipe *inPipe = [NSPipe new]; // pipe for shell input
NSPipe *outPipe = [NSPipe new]; // pipe for shell output
NSTask *task = [NSTask new];
[task setLaunchPath:@"/bin/sh"];
[task setStandardInput:inPipe];
[task setStandardOutput:outPipe];
[task launch];
// Wait for standard input ...
[input waitForDataInBackgroundAndNotify];
// ... and wait for shell output.
[[outPipe fileHandleForReading] waitForDataInBackgroundAndNotify];
// Wait asynchronously for standard input.
// The block is executed as soon as some data is available on standard input.
[[NSNotificationCenter defaultCenter] addObserverForName:NSFileHandleDataAvailableNotification
object:input queue:nil
usingBlock:^(NSNotification *note)
{
NSData *inData = [input availableData];
if ([inData length] == 0) {
// EOF on standard input.
[[inPipe fileHandleForWriting] closeFile];
} else {
// Read from standard input and write to shell input pipe.
[[inPipe fileHandleForWriting] writeData:inData];
// Continue waiting for standard input.
[input waitForDataInBackgroundAndNotify];
}
}];
// Wait asynchronously for shell output.
// The block is executed as soon as some data is available on the shell output pipe.
[[NSNotificationCenter defaultCenter] addObserverForName:NSFileHandleDataAvailableNotification
object:[outPipe fileHandleForReading] queue:nil
usingBlock:^(NSNotification *note)
{
// Read from shell output
NSData *outData = [[outPipe fileHandleForReading] availableData];
NSString *outStr = [[NSString alloc] initWithData:outData encoding:NSUTF8StringEncoding];
NSLog(@"output: %@", outStr);
// Continue waiting for shell output.
[[outPipe fileHandleForReading] waitForDataInBackgroundAndNotify];
}];
[task waitUntilExit];
}
return 0;
}
关于objective-c - 如何在一致的环境中循环使用 NSTask 运行终端命令?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13217415/
我正在尝试在存档之前将 Mac 的地址簿复制到保存位置。这是我的代码: // whoami let whoam : NSTask = NSTask()
我正在将 ASIHTTPRequest 集成到我的应用程序中,并包含一些在 XCode 中找到的受支持的框架,但在此 API 的一个文件中,我在此声明中收到错误“NSTask 未声明”...NSTas
昨天我read somewhere that NSTask isn't thread safe这让我很困扰,因为我在 NSThread 中运行 NSTask,并且到目前为止还没有遇到任何线程问题。 我
我有一个可以通过此终端命令导入 XML 文件的应用程序: open /path/to/main\ app.app --args myXML.xml 这非常有效,没有任何问题。我已经使用 Applesc
我正在尝试学习以任务进程可以接受输入文件重定向作为参数的方式编写NSTask。在传统的 unix system() 命令中,这对代码来说是微不足道的,但对于我的应用程序的需求来说,其可控性还远远不够。
我正在尝试使用 NSTask 运行 UNIX 'apropos' 命令。这是我的代码: NSTask *apropos = [[NSTask alloc] init]; NSPipe *pipe =
我正在使用 NSTask 来获取/usr/bin/man 的输出。我得到了输出,但没有格式化(粗体、下划线)。应该看起来像这样: 粗体带有下划线的文本 (请注意,斜体文本实际上带有下划线,只是此处没有
假设一个基于 Cocoa 的沙盒应用程序生成了一个 SSH 实例。到目前为止一切顺利,SSH 进程正在启动。 问题是,如何允许子进程读取文件(例如 ~/.ssh/config 或 ~/.ssh/kno
此代码用于获取进程的标准输出 NSTask * task; NSPipe * pipe; NSFileHandle * fileHandle;
我在执行不同的 NSTask 时遇到问题。相同的launchPath,不同的参数。我有一个类,其实例管理自己的 NSTask 对象,并根据参数初始化这些实例 - 正在创建依赖的 NSTask 对象。我
我收到了一份来自 NSTask 的 -launch 崩溃现场的报告。 有问题的代码是: NSTask *task = [[NSTask alloc] init]; [task setLaunchPat
我正在编写一个任务来访问 OpenSSL 二进制文件。如果我复制/粘贴不带单引号的命令,那么它在终端中可以完美运行。 我不断将引用粘贴到命令中。这是代码/错误... let keySizeValue
在 NSTask 的源代码中,我在 waitUntilExit 方法中发现了一个有趣的地方: - (void) waitUntilExit { NSTimer *timer = nil;
我正在使用 NStask 来获取文件夹大小。它对于普通文件路径(如 home/ABC/Users/testUser/Documents)工作正常。但它没有显示 home/ABC/Users/testU
OS X 10.6.8、Carbon、C++ 应用。 我想从 shell 运行命令并以字符串形式返回结果,然后用作另一个函数的参数。 df/|尾-n +2 | awk '{ print $1 }' 但
我使用 NSTask 和 setStandardOutput 将命令行工具的标准输出重定向到我的程序,以便我可以使用它进行处理。这很好用,但作为一个副作用,当我运行程序时,工具的输出显示为输出。我想完
我正在尝试使用 NSTask 将二进制 plist 转换为 xml,尽管遇到了一个我不太理解的错误。如果我将命令 NSTask 失败并将其复制到命令行,它就可以正常工作。希望有人能告诉我出了什么问题。
我需要使用 NSTask 按顺序运行多个命令,并且想知道什么是判断任务是否已完成的好方法,以便我可以继续执行下一个命令。我正在使用“sox”(我将其包含在我的应用程序包中)使用输入音频文件创建临时音频
这个问题已经有答案了: NSTask NSPipe - objective c command line help (2 个回答) 已关闭2 年前。 我使用 NSTask 如下: NSTask
我正在使用 NSTask 在 Cocoa 中执行可执行文件。可执行文件正在创建文件。 有什么方法可以找出该可执行文件在执行过程中创建了哪些文件? 谢谢。 最佳答案 Instruments 中有一个工具
我是一名优秀的程序员,十分优秀!