NSTask

通过NSTask完成命令执行、交互、读写需要用到3个class

NSTask、NSPipe、NSFileHandle

NSTask的主要设置参数

1、初始化

2、设置launchPath、arguments、standardInput、standardOutput、standardError

3、NSPipe转化为NSFileHandle

 

NSTask.h API 

typedef NS_ENUM(NSInteger, NSTaskTerminationReason) {
    NSTaskTerminationReasonExit = 1,
    NSTaskTerminationReasonUncaughtSignal = 2
} API_AVAILABLE(macos(10.6)) API_UNAVAILABLE(ios, watchos, tvos);

@interface NSTask : NSObject

// Create an NSTask which can be run at a later time
// An NSTask can only be run once. Subsequent attempts to
// run an NSTask will raise.
// Upon task death a notification will be sent
//   { Name = NSTaskDidTerminateNotification; object = task; }
//

- (instancetype)init NS_DESIGNATED_INITIALIZER;

// these methods can only be set before a launch
@property (nullable, copy) NSURL *executableURL API_AVAILABLE(macos(10.13)) API_UNAVAILABLE(ios, watchos, tvos);
@property (nullable, copy) NSArray<NSString *> *arguments;
@property (nullable, copy) NSDictionary<NSString *, NSString *> *environment; // if not set, use current
@property (nullable, copy) NSURL *currentDirectoryURL API_AVAILABLE(macos(10.13)) API_UNAVAILABLE(ios, watchos, tvos);

// standard I/O channels; could be either an NSFileHandle or an NSPipe
@property (nullable, retain) id standardInput;
@property (nullable, retain) id standardOutput;
@property (nullable, retain) id standardError;

// actions
- (BOOL)launchAndReturnError:(out NSError **_Nullable)error API_AVAILABLE(macos(10.13)) API_UNAVAILABLE(ios, watchos, tvos);

- (void)interrupt; // Not always possible. Sends SIGINT.
- (void)terminate; // Not always possible. Sends SIGTERM.

- (BOOL)suspend;
- (BOOL)resume;

// status
@property (readonly) int processIdentifier;
@property (readonly, getter=isRunning) BOOL running;

@property (readonly) int terminationStatus;
@property (readonly) NSTaskTerminationReason terminationReason API_AVAILABLE(macos(10.6)) API_UNAVAILABLE(ios, watchos, tvos);

/*
A block to be invoked when the process underlying the NSTask terminates.  Setting the block to nil is valid, and stops the previous block from being invoked, as long as it hasn't started in any way.  The NSTask is passed as the argument to the block so the block does not have to capture, and thus retain, it.  The block is copied when set.  Only one termination handler block can be set at any time.  The execution context in which the block is invoked is undefined.  If the NSTask has already finished, the block is executed immediately/soon (not necessarily on the current thread).  If a terminationHandler is set on an NSTask, the NSTaskDidTerminateNotification notification is not posted for that task.  Also note that -waitUntilExit won't wait until the terminationHandler has been fully executed.  You cannot use this property in a concrete subclass of NSTask which hasn't been updated to include an implementation of the storage and use of it.  
*/
@property (nullable, copy) void (^terminationHandler)(NSTask *) API_AVAILABLE(macos(10.7)) API_UNAVAILABLE(ios, watchos, tvos);

@property NSQualityOfService qualityOfService API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0)); // read-only after the task is launched

@end

@interface NSTask (NSTaskConveniences)

+ (nullable NSTask *)launchedTaskWithExecutableURL:(NSURL *)url arguments:(NSArray<NSString *> *)arguments error:(out NSError ** _Nullable)error terminationHandler:(void (^_Nullable)(NSTask *))terminationHandler API_AVAILABLE(macos(10.13)) API_UNAVAILABLE(ios, watchos, tvos);

- (void)waitUntilExit;
	// poll the runLoop in defaultMode until task completes

@end

@interface NSTask (NSDeprecated)

@property (nullable, copy) NSString *launchPath API_DEPRECATED_WITH_REPLACEMENT("executableURL", macos(10.0, API_TO_BE_DEPRECATED)) API_UNAVAILABLE(ios, watchos, tvos);
@property (copy) NSString *currentDirectoryPath API_DEPRECATED_WITH_REPLACEMENT("currentDirectoryURL", macos(10.0, API_TO_BE_DEPRECATED)) API_UNAVAILABLE(ios, watchos, tvos); // if not set, use current

- (void)launch API_DEPRECATED_WITH_REPLACEMENT("launchAndReturnError:", macos(10.0, API_TO_BE_DEPRECATED)) API_UNAVAILABLE(ios, watchos, tvos);

+ (NSTask *)launchedTaskWithLaunchPath:(NSString *)path arguments:(NSArray<NSString *> *)arguments API_DEPRECATED_WITH_REPLACEMENT("launchedTaskWithExecutableURL:arguments:error:", macos(10.0, API_TO_BE_DEPRECATED)) API_UNAVAILABLE(ios, watchos, tvos);
// convenience; create and launch

@end

FOUNDATION_EXPORT NSNotificationName const NSTaskDidTerminateNotification;

初始化

- (instancetype)init
//声明并初始化, 
//[[NSTask alloc] init]
//[NSTask new]

// these methods can only be set before a launch

@property (nullable, copy) NSArray<NSString *> *arguments;
//cmd执行所需要的参数,如ping指令
//  /sbin/ping -c 1 192.168.1.1
//  /sbin/ping是指令
//  后边的@"-c 1 192.168.1.1"就是参数
[task setArguments: arguments];

@property (nullable, copy) NSDictionary<NSString *, NSString *> *environment; 
// if not set, use current
// 环境变量的设置通常也是比较少的
// 就比如我们在执行一个python脚本时,有时候需要先配置Python的环境变量
// PYTHON_PATH = "~/Desktop/python/package/?.py"
// 这个变量的作用就在于此
[task setEnvironment: environments];

[task setLaunchPath: @"/sbin/ping"];

// standard I/O channels; could be either an NSFileHandle or an NSPipe

@property (nullable, retain) id standardInput;
//与NSTask交互的输入接口
//如FTP,telnet等需要交互的shell cmd,都需要输入交互
@property (nullable, retain) id standardOutput;
//NSTask的输出接口
@property (nullable, retain) id standardError;
//NSTask执行发生错误时的输出信息接口

//这三种接口通常是NSPipe类型的定义
//如
//NSPipe *pipe = [NSPipe pipe];

[task setStandardOutput:outputPipe];
[task setStandardError:errorPipe];
//NSPipe与NSFileHandle是可以转化的
NSFileHandle *file = [pipe fileHandleForReading];

[task launch];

// 获取运行结果
[[self->task.standardOutput fileHandleForReading] setReadabilityHandler:^(NSFileHandle *aFileHandle){
    @autoreleasepool{
        NSString *receiveString =[[NSString alloc] initWithData:[aFileHandle availableData] encoding:NSUTF8StringEncoding];
        NSLog(@"%@",receiveString);
    }
}];
    
// 获取运行结果
NSData *data = [file readDataToEndOfFile];
NSString *receiveString = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];

NSPipe

@interface NSPipe : NSObject

@property (readonly, retain) NSFileHandle *fileHandleForReading;
@property (readonly, retain) NSFileHandle *fileHandleForWriting;

+ (NSPipe *)pipe;

@end

有些时候,如果我们仅仅需要执行一个shell 指令,而不关心其输入和输出情况,可使用更底层的system()来直接完成
比如kill掉一个进程
system()所在位置:xcode中usr/include/stdlib.h

system("kill -9 $(ps aux |grep 'ping'|grep -v 'grep' |awk '{print $2}')");

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

auspark

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值