Execute a terminal command from a Cocoa app

后端 未结 12 2304
既然无缘
既然无缘 2020-11-22 06:34

How can I execute a terminal command (like grep) from my Objective-C Cocoa application?

12条回答
  •  孤城傲影
    2020-11-22 07:02

    in the spirit of sharing... this is a method I use frequently to run shell scripts. you can add a script to your product bundle (in the copy phase of the build) and then have the script be read and run at runtime. note: this code looks for the script in the privateFrameworks sub-path. warning: this could be a security risk for deployed products, but for our in-house development it is an easy way to customize simple things (like which host to rsync to...) without re-compiling the application, but just editing the shell script in the bundle.

    //------------------------------------------------------
    -(void) runScript:(NSString*)scriptName
    {
        NSTask *task;
        task = [[NSTask alloc] init];
        [task setLaunchPath: @"/bin/sh"];
    
        NSArray *arguments;
        NSString* newpath = [NSString stringWithFormat:@"%@/%@",[[NSBundle mainBundle] privateFrameworksPath], scriptName];
        NSLog(@"shell script path: %@",newpath);
        arguments = [NSArray arrayWithObjects:newpath, nil];
        [task setArguments: arguments];
    
        NSPipe *pipe;
        pipe = [NSPipe pipe];
        [task setStandardOutput: pipe];
    
        NSFileHandle *file;
        file = [pipe fileHandleForReading];
    
        [task launch];
    
        NSData *data;
        data = [file readDataToEndOfFile];
    
        NSString *string;
        string = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
        NSLog (@"script returned:\n%@", string);    
    }
    //------------------------------------------------------
    

    Edit: Included fix for NSLog problem

    If you are using NSTask to run a command-line utility via bash, then you need to include this magic line to keep NSLog working:

    //The magic line that keeps your log where it belongs
    [task setStandardInput:[NSPipe pipe]];
    

    In context:

    NSPipe *pipe;
    pipe = [NSPipe pipe];
    [task setStandardOutput: pipe];
    //The magic line that keeps your log where it belongs
    [task setStandardInput:[NSPipe pipe]];
    

    An explanation is here: http://www.cocoadev.com/index.pl?NSTask

提交回复
热议问题