在Objective-C中调用shell脚本、shell命令

最近在研究自动化打包,不可避免的要涉及到shell命令的使用。

我的想法是写好shell脚本后用oc写个图形化界面来调用。

查了资料后知道oc调用shell使用NSTask这个类。

本文分两部分,Objective-C调用shell脚本、Objective-C调用shell命令

1.Objective-C调用shell脚本

NSTask调用shell脚本的一般使用方法是:

//脚本路径
NSString shellPath = @"/Users/Apple/Desktop/test.sh";
NSTask *task = [[NSTask alloc] init];
[task setLaunchPath: @"/bin/sh"];
NSArray *arguments =@[shellPath];
[task setArguments: arguments];
[task launch];

其中shellPath就是脚本所在的路径,如果有需要传入脚本的参数的话就添加在arguments里:

NSArray *arguments =@[shellPath,@"argument1",@"argument2"....];

NSTask有个-(void)waitUntilExit方法,添加在[task launch]之后可以等待脚本执行完再执行接下来的代码:

NSString shellPath = @"/Users/Apple/Desktop/test.sh";
NSTask *task = [[NSTask alloc] init];
[task setLaunchPath: @"/bin/sh"];
NSArray *arguments =@[shellPath];
[task setArguments: arguments];
[task launch]; 
[task waitUntilExit];
// 其他的代码

不过这样有个问题是在图形化界面中阻塞主线程的话会导致程序卡死,所以要把它放到多线程里执行:

dispatch_async(dispatch_get_global_queue(QOS_CLASS_UTILITY, 0), ^{

NSString shellPath = @"/Users/Apple/Desktop/test.sh";
NSTask *task = [[NSTask alloc] init];
[task setLaunchPath: @"/bin/sh"];
NSArray *arguments =@[shellPath];
[task setArguments: arguments];
[task launch]; 
[task waitUntilExit];
// 其他的代码
});

封装一下,从外部传入脚本路径和参数,执行完毕后通过block回调:

+(void)runShellWithArguments:(NSArray *)arguments completeBlock:(dispatch_block_t)completeBlock{
    dispatch_async(dispatch_get_global_queue(QOS_CLASS_UTILITY, 0), ^{
        NSTask *task = [NSTask new];
        [task setLaunchPath:@"/bin/sh"];
        [task setArguments:arguments];
        [task launch];
        [task waitUntilExit];
        dispatch_async(dispatch_get_main_queue(), ^{
            if (completeBlock) {
                completeBlock();
            }
        });
    });
}

这里我把脚本路径和参数放到同一个数组里了,第0位是脚本路径,之后是参数。

2.Objective-C调用shell命令

NSTask调用shell命令的一般方法是:

NSTask *task = [[NSTask alloc] init];
[task setLaunchPath: @"/bin/sh"];
NSArray *arguments = [NSArray arrayWithObjects: @"-c",@"echo hello world", nil];
[task setArguments: arguments];

同样封装一下:

+(void)runShellWithCommand:(NSString *)command completeBlock:(dispatch_block_t)completeBlock{
    dispatch_async(dispatch_get_global_queue(QOS_CLASS_UTILITY, 0), ^{
        NSTask *task = [[NSTask alloc] init];
        [task setLaunchPath: @"/bin/sh"];
        NSArray *arguments;
        arguments = [NSArray arrayWithObjects:@"-c",command, nil];
        [task setArguments: arguments];
        [task launch];
        [task waitUntilExit];
        dispatch_async(dispatch_get_main_queue(), ^{
            if (completeBlock) {
                completeBlock();
            }
        });
    });
}

 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Objective-C,您可以使用`NSThread`类的`callStackReturnAddresses`方法来获取调用栈的返回地址。然后,您可以使用`dladdr()`函数来解析这些返回地址,以获取调用者的起始地址。 以下是一个示例代码,展示了如何在Objective-C获取调用者的起始地址: ```objective-c #import <Foundation/Foundation.h> #include <dlfcn.h> void printCallerFunctionAddress() { NSArray<NSNumber *> *callStackReturnAddresses = [NSThread callStackReturnAddresses]; if (callStackReturnAddresses.count >= 2) { void *returnAddress = (void *)(uintptr_t)callStackReturnAddresses[1].unsignedIntegerValue; Dl_info dlInfo; if (dladdr(returnAddress, &dlInfo) != 0 && dlInfo.dli_sname != NULL) { printf("Caller function start address: %p\n", dlInfo.dli_saddr); } } } void foo() { printCallerFunctionAddress(); } int main(int argc, const char * argv[]) { @autoreleasepool { foo(); } return 0; } ``` 在上述示例,我们首先使用`[NSThread callStackReturnAddresses]`方法获取调用栈的返回地址数组。然后,我们通过索引1获取上一级函数的返回地址。接下来,我们使用`dladdr()`函数解析返回地址,将结果存储在`dlInfo`结构体。最后,我们打印调用者函数的起始地址(`dlInfo.dli_saddr`)。 请注意,`dladdr()`函数在解析返回地址时,可能会依赖于符号表信息。在某些情况下,可能无法获取准确的起始地址。此外,这种方法也依赖于平台和编译器的特定实现,因此在不同的环境可能会有差异。 希望这能够帮助到您。如果还有其他问题,请随时提问。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值