macOS Launchd 启动任务

2023-11-30  本文已影响0人  游城十代2dai

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

0x00 Launchd 目录配置

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

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

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

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

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

0x01 Launchd Plist 配置

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

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

使用 Program 和 ProgramArguments

只使用 ProgramArguments

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

<!-- 每天的9:30执行 -->
<key>StartCalendarInterval</key>
<dict>
  <key>Minute</key>
  <integer>30</integer>
  <key>Hour</key>
  <integer>9</integer>
</dict>
<!-- 每小时执行一次 -->
<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 "你好贾维斯"
上一篇 下一篇

猜你喜欢

热点阅读