cd
とpwd
はシェル組み込みコマンドです。タスクを実行すると
/bin/sh -c "cd /"
変更された作業ディレクトリを呼び出しプロセスに戻す方法はありません。変数を設定する場合も同じ問題が存在しますMYVAR=myvalue
。
これらの行を個別に解析して、環境を更新してみてください。しかし、次のような複数行のコマンドはどうですか
for file in *.txt
do
echo $file
done
各行を別々のNSTask
プロセスに送信することによってそれをエミュレートすることはできません。
あなたができる唯一のことは、単一の /bin/sh
プロセスをNSTask
で開始し、すべての入力行をそのプロセスの標準入力にフィードすることです。readDataToEndOfFile
ただし、 を使用して出力を読み取ることはできませんが、非同期で読み取る必要があります ( を使用[[pipe fileHandleForReading] waitForDataInBackgroundAndNotify]
)。
要するに、(単一の)シェルを実行するだけでターミナルをシミュレートできます。
追加:おそらく、アプリの出発点として以下を使用できます。(エラーチェックはすべて省略しています。)
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;
}