菜鸡,为了给Mac设置后台定时任务,我搞了两天

七哥爱编程

共 2998字,需浏览 6分钟

 · 2021-05-01

img

Mac 使用 Launchctl 设置后台定时任务无效的解决方法

写在前面

如果只是为了解决问题不需要掌握排查方法的老哥,可以直接看我总结的一些任务失效的原因:

问题大致有以下几种:

  • shell 脚本 没有加 #!/bin/sh ;
  • .plist 中定义的日志文件目录不能被当前用户访问,使用 chmod 修改文件目录权限或者日志修改路径;
  • 直接执行脚本完美运行,launchd 执行时就报错,这是因为系统在自动运行shell脚本时是不会加载任何环境变量的。所以可能出现自己手工运行脚本正常,但是在调度任务中出错,这时需要在shell脚本中添加:source ~/.bashrc 或者 source ~/.zshrc ,选择哪个取决你shell使用的 bash 还是 zsh ;
  • shell脚本没有可执行权限,使用 chmod 添加执行权限(我的就是这个原因,因为使用 sh xxx.sh 执行没有问题,一直忽略了脚本自身的执行权限,sh 执行是将脚本交给 bash 命令去解析执行,相当于被人家调用执行,和本身直接运行不一样);

这些问题都会导致我们的任务状态为 78,这实在是太坑了。可以使用 launchctl list | grep '你的任务名' 查看任务状态,如果你的问题不在上面这些中,那么我推荐你往下看。

背景

这两天在解决 github 访问慢,以及图片无法加载问题时,因为要修改本地 hosts 文件,定时去寻找最新的 ip 然后替换不是一个程序员应该做的事情,所以我就想写一个脚本,然后后台定时调度来实时更新最新的 iphosts 文件。

使用 Launchctl

mac 上可以使用 launchctl 来定义管理定时任务。

通过简单的学习,launchctl是通过 .plist 来得知系统中有哪些东西需要被管理的。所以简单的来说,想要新增被管理项,本质上就是新增一个.plist放入苹果的管理文件夹下,然后使其被加载后执行。苹果根据用户的角色提供了不同的Launch存放位置:

~/Library/LaunchAgents          # 当前用户定义的任务
/Library/LaunchAgents           # 系统管理员定义的任务
/Library/LaunchDaemons          # 管理员定义的系统守护进程任务
/System/Library/LaunchAgents    # 苹果定义的任务
/System/Library/LaunchDaemons   # 苹果定义的系统守护进程任务

很显然,我们是最好不要使用下面两个位置的(苹果定义的),我们用一个目录即可,为当前用户新增一个定时任务。

具体如何编写本文就不一一记录了,直接用搜索引擎搜索一大堆教程,大体分为以下三步:

  1. 定义要执行的shell脚本;
  2. 编写调度任务 .pllist 文件;
  3. 将任务添加到调度列表中;

定时任务不生效

网上的教程大多数是按照这三步设置好后,就可以定时调度了,但是我设置完后,也没报错,可是就是不生效,脚本没有被调度。这就很尴尬,苦苦搜索了俩小时,各种教程都是说如果使用 launchctl 的,我对比了代码也没啥区别呀,而且用 plutil -lint xxx.plist 这个命令校验,直接 sh xxx.sh 测试都是没问题的。

百思不得其解之后,突然在一片文章中找到了端倪:

在使用 launchctl list 的时候会列出所有任务能够看到任务的状态(status),如果出现非0的状态码就表示任务出错了,可以使用:launchctl error [errorCode]来查看。

看到这里,我发现我的任务状态是78:

发现了任务确实有问题,然后使用 launchctl error 78 来查看:

好像,也没啥帮助,提示函数没实现。然后用这个错误去 google 搜索(google搜索还是香呀),发现了端倪:

有人遇到了和我同样的错误,认同数最高的解答方案是推荐使用 launchcontrol 这个可视化的工具,没办法,装呗~~。谁叫咱的问题解决不了呢。

解决方法

使用 mac 系统的 homebrew 安装 :

brew install launchcontrol

稍等片刻,安装完成后,打开软件,我激动了,尼玛,这个错误一下就提示出来了:

最底下提示一目了然,脚本没有可执行权限呀!!

我折腾了好几天,代码核对了无数遍,也不是没有怀疑过这个原因,所以我还用 sh xxx.sh 执行过了,但是我忽略了 sh 执行是将脚本作为参数传给 bash 来解释运行,而直接使用 ./xxx.sh 执行脚本是需要可执行权限的,哎,我也太菜了。

既然发现了问题,那就好办了,执行:chmod 744 xxx.sh , 然后在打开 launchcontrol 软件:

报错已经没有了,取而代之的是一片绿油油的盎然景象。至此,困扰了我两天共计花费4小时的问题,终于搞定了!

这个软件不是免费的,但是可以选择试用版,排查问题足够了,如果需要使用高级功能的免费激活版本,文章无法直接上传,可以关注公众号:七哥编程说,回复 launchd 获取。

总结

  • 做程序员需要耐心,如果遇到问题搞不出来我直接关掉电脑,此事就不了了之了;
  • 学会用 google 搜索,真的是太重要了,我开始一直用百度搜索全是csdn上的那些千篇一律的如果设置定时任务的文章,后来用来google搜索,同样的关键字结果排第一的是 stackoverflow 的解决方案;
  • 解决 launchctl 任务设置失效的问题,建议安装 launchcontrol 这个可视化的工作,简直太方便了,允许你在Mac上管理和调试系统和用户服务,提高使用效率。



封面来源:pixabay 

作者:七哥


            欢迎大家点个在看,分享至朋友圈


七哥也开通了视频号:【程序员七哥】,以视频的方式和大家见面,扫码关注,第一时间收到视频更新。所见所领,皆是生活。慢慢来,努力一点,你我共同成长...



最近建立了一个技术群,如果你想了解到更多关于IT行业的技术以及工作生活中遇到的问题,可以加我微信备注:【进群】,拉你进群交流,这里有和你同频的朋友。



来自七哥的无脑推荐阅读:


我是如何从电脑小白走上编程之路


一个线程中断引发Bug的“爆肝”排查经历

浏览 31
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报