Mac开发-launchctl执行脚本

launchctl是一个统一的服务管理框架,启动、停止和管理守护进程、应用程序、进程和脚本。
我们一般使用其定时执行任务,例如在某一时间执行脚本

编写定时任务

plist文件

新建一个plist文件 com.haocaihaocai.task.plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>Label</key>
    <string>com.haocaihaocai.task</string>

    <key>ProgramArguments</key>
    <array>
      <string>/tmp/shelltask.sh</string>
    </array>

    <key>StartCalendarInterval</key>
    <dict>

      <key>Minute</key>
      <integer>10</integer>

      <key>Hour</key>
      <integer>15</integer>

    </dict>
    <key>StandardOutPath</key>
    <string>/tmp/shelltask.log</string>
    <key>StandardErrorPath</key>
    <string>/tmp/shelltask.err</string>

  </dict>
</plist>

即如下图
Mac开发-launchctl执行脚本_第1张图片
使用终端添加执行权限
gensee$ sudo chmod 600 /Users/gensee/Desktop/study/launchctlDemo/launchctlDemo/com.haocaihaocai.task.plist

权限不是600的话会提示 Path had bad ownership/permissions

Plist部分参数说明:
Label:对应的需要保证全局唯一性;
Program:要运行的程序;
ProgramArguments:命令语句
StartCalendarInterval:运行的时间,单个时间点使用dict,多个时间点使用 array
StartInterval:时间间隔,与StartCalendarInterval使用其一,单位为秒
StandardInPath、StandardOutPath、StandardErrorPath:标准的输入输出错误文件,这里建议不要使用 .log 作为后缀,会打不开里面的信息。
定时启动任务时,如果涉及到网络,但是电脑处于睡眠状态,是执行不了的,这个时候,可以定时的启动屏幕就好了。

plist文件位置

赋值到launchctl的执行位置,有如下几种

  • ~/Library/LaunchAgents 由用户自己定义的任务项
  • /Library/LaunchAgents 由管理员为用户定义的任务项
  • /Library/LaunchDaemons由管理员定义的守护进程任务项
  • /System/Library/LaunchAgents 由Mac OS X为用户定义的任务项
  • /System/Library/LaunchDaemons 由Mac OS X定义的守护进程任务项

LaunchDaemonsLaunchAgents的区别?
LaunchDaemons是用户未登陆前就启动的服务(守护进程)。
LaunchAgents是用户登陆后启动的服务(守护进程)。

移动到 ~/Library/LaunchAgents 目录下

加载命令

加载任务, -w选项会将plist文件中无效的key覆盖掉,建议加上
$ launchctl load -w com.haocaihaocai.task.plist
删除任务
$ launchctl unload -w com.haocaihaocai.task.plist
查看任务列表, 使用 grep ‘任务部分名字’ 过滤
$ launchctl list | grep 'com.haocaihaocai'
开始任务 - 这里需要是任务名
$ launchctl start com.haocaihaocai.task
结束任务
$ launchctl stop com.haocaihaocai.task

如果任务呗修改了,那么必须先unload,然后重新load start可以测试任务,这个是立即执行,不管时间到了没有
执行start和unload前,任务必须先load过,否则报错 stop可以停止任务

Warning
执行的shell脚本需要添加可执行权限sudo chmod 777,建议自己先在命令行中运行一遍呢,看是否可以直接执行

在开发中使用NSAppleScript执行

//如果你的命令需要管理员权限,则设置isAmin=YES
- (BOOL) runProcessAsAdministrator:(NSString*)scriptPath
                     withArguments:(NSArray *)arguments
                            output:(NSString **)output
                  errorDescription:(NSString **)errorDescription
                   asAdministrator:(BOOL)isAdmin{
    
    NSString * allArgs = [arguments componentsJoinedByString:@" "];
    NSString * fullScript = [NSString stringWithFormat:@"%@ %@", scriptPath, allArgs];
    
    NSDictionary *errorInfo = [NSDictionary new];
    NSString *script =  [NSString stringWithFormat:@"do shell script \"%@\" %@", fullScript,isAdmin?@"with administrator privileges":@""];
    
    NSAppleScript *appleScript = [[NSAppleScript new] initWithSource:script];
    NSAppleEventDescriptor * eventResult = [appleScript executeAndReturnError:&errorInfo];
    
    // Check errorInfo
    if (! eventResult)
    {
        // Describe common errors
        *errorDescription = nil;
        if ([errorInfo valueForKey:NSAppleScriptErrorNumber])
        {
            NSNumber * errorNumber = (NSNumber *)[errorInfo valueForKey:NSAppleScriptErrorNumber];
            if ([errorNumber intValue] == -128)
                *errorDescription = @"The administrator password is required to do this.";
        }
        
        // Set error message from provided message
        if (*errorDescription == nil)
        {
            if ([errorInfo valueForKey:NSAppleScriptErrorMessage])
                *errorDescription =  (NSString *)[errorInfo valueForKey:NSAppleScriptErrorMessage];
        }
        
        return NO;
    }
    else
    {
        // Set output to the AppleScript's output
        *output = [eventResult stringValue];
        
        return YES;
    }
}

使用 NSAppleScript 可以在代码中执行。

测试demo https://github.com/shengpeng3344/launchctlDemo

参考文章 https://www.jianshu.com/p/4addd9b455f2

你可能感兴趣的:(Mac开发)