macOS Launchd 启动任务

macOS 通过启动硬盘指定目录下的配置文件,来完成启动任务。这些文件为plist,本质上是XML。

0x00 Launchd 目录配置

Mac下Launchd的plist文件放置的目录有

由用户自己定义的任务项
~/Library/LaunchAgents        
          
由管理员为用户定义的任务项
/Library/LaunchAgents                    

由管理员定义的守护进程任务项
/Library/LaunchDaemons             

由 macOS 为用户定义的任务项
/System/Library/LaunchAgents 
      
由 macOS 定义的守护进程任务项
/System/Library/LaunchDaemons 

其中 LaunchDaemons 和 LaunchAgents 的区别是什么?

  • LaunchDaemons 是用户未登陆前就启动的服务(守护进程)
  • LaunchAgents 是用户登陆后启动的服务(守护进程)

0x01 Launchd Plist 配置

标签 必填 说明
Label 标识符,用来表示该任务的唯一性
Program 程序名称,用来说明运行哪个程序、脚本
ProgramArguments 同上,与Program二选一或一起使用,只是可以运行多个程序、可带参数
WatchPaths 监控路径,当路径文件有变化是运行程序,也是数组
RunAtLoad 是否在加载的同时启动
StartCalendarInterval 运行的时间,单个时间点使用dict,多个时间点使用 array -> dict
StartInterval 时间间隔,与StartCalendarInterval使用其一,单位为秒
StandardInPath、StandardOutPath、StandardErrorPath 标准的输入输出错误文件,这里建议不要使用.log作为后缀,会打不开里面的信息

两种指定要执行命令的方法:

使用 Program 和 ProgramArguments

  • Program, 运行命令或要执行文件路径
  • ProgramArguments, 执行时传入参数

只使用 ProgramArguments

  • ProgramArguments 的每个参数为要执行的命令或文件路径,其它参数为传入参数

两种设置执行时间的方法:

  • StartCalendarInterval 使用元素Minute, Hour, Day, Month, Weekday指定执行时间,如:
<!-- 每天的9:30执行 -->
<key>StartCalendarInterval</key>
<dict>
  <key>Minute</key>
  <integer>30</integer>
  <key>Hour</key>
  <integer>9</integer>
</dict>
  • StartInterval 设置执行的时间间隔,单位为秒
<!-- 每小时执行一次 -->
<key>StartInterval</key>
<integer>3600</integer>

0x02 Launchd 定时任务

编写我的 shell 脚本文件

功能是在 macOS 开机后自动执行下面的脚本, 开启内网穿透的功能, 可以忽略我的脚本内容, 替换成你想用的脚本

# launch.sh
#! /bin/bash

export ZWY_HOME=/Users/mb
export ZWY_DIR=$ZWY_HOME/ZwyShell
export ZWY_DIR_FeiGeNAT=$ZWY_HOME/ZwyShell/darwin_amd64_client
export PATH=$PATH:$ZWY_DIR:$ZWY_DIR_FeiGeNAT

LOG_PATH=$ZWY_DIR/launch/launch.log

echo "====start zwy launch====" >> $LOG_PATH

echo $(date +"%Y-%m-%d %H:%M:%S") >> $LOG_PATH
echo "npc is in "`which npc` >> $LOG_PATH

npc -server=nps.xxxx.press:8024 -vkey=zwy -type=tcp > $ZWY_DIR_FeiGeNAT/npc_home.log

注意:
可以使用 chmod a+x launch.sh 给权限变成可执行文件, 也可以用 bash 命令调用

编写 Plist 文件

~/Downloads 下面创建一个 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.zwy.home</string>
    <key>ProgramArguments</key>
    <array>
        <string>bash</string>
        <string>/Users/mb/ZwyShell/launch/launch.sh</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>Version</key>
    <string>3</string>
</dict>
</plist>

可以用 plutil -lint com.zwy.home.plist 来验证 Plist 格式是否正确

加载命令

launchctl 是一个统一的服务管理框架,启动、停止和管理守护进程、应用程序、进程和脚本


# 加载任务, -w选项会将plist文件中无效的key覆盖掉,建议加上
launchctl load -w com.zwy.home.plist
launchctl start com.zwy.home

# 删除任务
launchctl stop com.zwy.home.plist
launchctl unload -w com.zwy.home

# 查看任务列表, 使用 grep '任务部分名字' 过滤
launchctl list | grep 'com.zwy.home.plist'

经验

如果执行 launchctl load 命令出现 com.zwy.home.plist: Path had bad ownership/permissions,需要为 plist 文件赋予600 权限或者 root 权限, 都可以尝试一下:

sudo chmod 600 path/com.zwy.home.plist

sudo chown root:wheel path/com.zwy.home.plist

执行 launchctl list 查看到你的执行结果, 其他错误可以用 launchctl error <insert numerical error code here>来查看具体错误:

$ launchctl list | grep 'com.zwy.home'
-    78    com.zwy.home # 错误结果
-    0      com.zwy.home # 正确结果

执行 launchctl list 具体描述如下:

1230    -   com.apple.speech.speechsynthesisd
353     -   com.apple.security.cloudkeychainproxy3
255     -   com.apple.secd
-       0   com.apple.sbd

第一列表示进程号,如果有在结果中罗列,但没有数字而只是一个横线,标志虽然已经loaded, 但没有运行
第二列是上次退出的状态号(the last exit code), 0表示成功,正数表示错误退出,负数表示收到信号后退出

如果 shell脚本输出如果有中文,中文部分乱码,则需要在shell脚本中指定编码:

#!/bin/bash

LANG=en_US.UTF-8
export LANG

echo "你好贾维斯"

2024-07-10 补充
有时候会遇到 exit code 为 1, 标识没有权限, 在我的这里, 实际上是 bash 没有权限访问磁盘文件, 在系统设置里添加自己的 bash 为完全磁盘访问权限即可, 查看 bash 在哪里, 用 which bash

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容