如何实现Shell脚本开机自运行

场景

工作中使用电脑要求使用相关的工作软件,开机自启动的

需求

工作日晚8点之后和周末都要自动关闭相关的工作软件

花了一点时间摸索出来,整理总结下便于以后回顾。

Shell脚本相关

根据以上需求,编写Shell脚本,脚本内容如下:

#!/bin/bash
limit_time=20
current_hour=`date "+%H"`
current_weekday=`date "+%w"`
killProcess(){
  procress_pids=`ps -ef | grep -E 'AliEntSafe|AliLang' | awk '{print $2}'`
  for pid in $procress_pids
  do
    kill -9 $pid
  done
}
# 周末
if [[ $current_weekday -eq 0 || $current_weekday -eq 6 ]]
then
  killProcess
# 工作日
elif [[ $current_hour -ge $limit_time ]]
then
  killProcess
fi

上面的脚本是一个简单逻辑的脚本很基础,对于初学者学习点有:

  • date获取小时和星期几
  • ps + grep获取指定进程,awk获取pid集合
  • kill杀死进程
  • if流程控制+for循环控制
  • 比较运算符相关

具体Shell教程可以去搜索看下,这里我介绍下我知道的Shell中使用到的各种括号的作用:

[]、()、[[]]、(())、{}

  • 执行命令并赋值给变量:“、()

    “和()都可以用来命令的执行,但是二者还是存在区别:

    • ()不是所有Shell都支持的,而“所有Shell都支持
    current_date=`date`
    current_date=$(date)
  • 一串命令执行:()、{}

    二者的区别和联系:

    • ()会重开一个子Shell进行执行,{}是在当前Shell中执行
    • 都是使用;分割命令,但()最后一个命令可以不要;,而{}必须要
    • {}中第一个命令前要加一空格
    (var=notes;echo $var)
    { var=notes;echo $var;}
  • 引用变量: {}

    var=notes
    echo $var
    echo ${var}
  • 用于判断语句中的条件包裹:[]、[[]]

    下面三个都是实现一样的功能

    if [ $var -lt 5 -a $var -gt 4 ]
    if [ $var -lt 5 ] && [ $var -gt 4 ]
    if [[ $var -lt 5 && $var -gt 4 ]]
  • 数组定义:()

    array=(1 2 3 4)
  • for循环条件包裹:(())

    下面都是实现1到10的遍历,可以看出:

    • for循环的数据源可以使命令或变量
    • 可以使用(())来包裹循环条件
    • 可是使用{n..m}来获取从n到m的数据,类似seq命令
    for i in `seq 1 10`;do echo $i;done
    for i in $(seq 1 10);do echo $i;done
    for ((i=1;i<=10;i++));do echo $i;done
    for i in {1..10};do echo $i;done

补充:

​ {}还可以实现列表的效果

ls {ex1,ex2,ex3}.sh 
# 等价
ls {ex{1..3}}.sh
# 等价
ls ex1.sh ex2.sh ex3.sh

在Linux中文件权限分为:可读、可写、可执行

需要赋予该sh文件(kill_process.sh)可执行权限
chmod a+x kill_process.sh

这样就赋予所有人可执行Shel脚本的权限了

使用launchd来实现脚本开机自执行

首先看看launchd的介绍,使用man launchd显示详情:
这里写图片描述
这里写图片描述

从上面截图中可以看出launchd相关的介绍,大致可知:

launchd:用于管理进程,系统级别或用户级别
对外的用户接口是launchctl命令,用户或管理员可以使用该命令添加或重启任务
launchd作为系统中第一个进程

这里写图片描述

设置launchd相关进程的具体目录是在FilES所列的,具体上分为系统级别和用户级别两类

设置自启动的一种方式就是在设置用户级别的任务:

即在/Library/LaunchAgents下建立plist文件

plist文件相关的可以使用man launchd.plist来查看相关的配置,实际上plist是xml文件配置

本次用于执行kill_process.sh文件的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.custom.sheet</string>
    <!-- 定义运行脚本具体路径 -->
    <key>ProgramArguments</key>
    <array>
        <string>/Library/LaunchAgents//kill_process.sh</string>
    </array>
    <!-- 定义是否在启动时运行 -->
    <key>RunAtLoad</key>
    <true/>
    <!-- 定义是否一直运行 -->
    <key>KeepAlive</key>
    <dict>
        <!-- 表示运行成功之后就退出任务 -->
        <key>SuccessfulExit</key>
        <true />
    </dict>
    <!-- 标准错误输出 -->
    <key>StandardErrorPath</key>
    <string>/dev/null</string>
    <key>StandardOutPath</key>
    <string>/dev/null</string>
</dict>
</plist>
  • 在/Library/LaunchAgents下定义名为com.custom.sheet.plist文件

  • 执行sudo chown root:wheel com.custom.sheet.list

  • 执行sudo chown root:wheel kill_process.sh

  • 使用sudo launchctl load /Library/LaunchAgents/com.custom.sheet.plist,加载任务到launchd即可

使用自动程序实现开机自运行

使用Mac上的自动操作生成app程序来实现开启自动执行
这里写图片描述

在上面的截图中选择应用程序,搜索运行shell脚本:
这里写图片描述

创建APP,定义脚本:

cd 脚本目录
open -a Terminal.app kill_process.sh

保存就行,然后将定义的app添加到开机自启动上就行,即系统偏好设置 - 用户与群组 - 登录项

总结

目前所知两种方式实现Shell脚本自启动:

  • 使用launchd来实现
  • 使用自动操作定义应用程序+启动项来实现,不过这种方式报错或有弹出框提示

猜你喜欢

转载自blog.csdn.net/s1879046/article/details/82286223