自动化Git提交

目标

  在每天的固定时间自动将今天修改的本地仓库提交到github,算是提高生产力的一种方式吧。

shell脚本

  首先要了解手工提交的时候执行的操作步骤

commite_repo.sh

  commite_repo.sh用于提交本地仓库到github

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#!/bin/bash

DATE=$(date +%s)
# 要提交到github的工程名称
CheckList=('Daily_knowledge_set','Daily_sh_set','Daily_ui_objc_set','Daily_ui_set','Daily_modules','Daily_leetcode_set')
TARGET="你的本地仓库地址"
# echo ${DATE}
cd ${TARGET}
for file in ${TARGET}/*
do
cd ${file}
echo ${file##*/}
git remote -v | grep fetch | awk '{print $2}' | git pull
done

for file in ${TARGET}/*
do
if echo "${CheckList[@]}" | grep -w ${file##*/} &>/dev/null; then
cd ${file}
# echo ${file}
git status | grep "nothing to commit" > /dev/null 2>&1
if [ $? != 0 ]; then
echo "提交新的Commit:"${file##*/}_${DATE}
git add .
git commit -m ${file##*/}_${DATE}
git push
else
echo "没有更改:"${file##*/}
fi
fi
done

提交博客到github

1
2
3
» ~  ~/.blog_ssh-add.sh
» ~ sudo hexo g
» ~ sudo hexo d

~/.blog_ssh-add.sh是为了解决因为ssh的证书不是默认的id_rsa,每次重启Mac提交博客,hexo都会报公钥错误的问题。

剩下两个是生成静态博客与部署到github的指令

因为使用了sudo,其中有一个密码验证的过程,在Hexo提交出现Permission denied (publickey)已经使用过expect来解决了,照葫芦画瓢写了如下脚本

exec_hexo.sh

1
2
3
4
5
6
7
8
9
10
11
#!/usr/local/bin/expect -f

spawn sudo hexo g
expect "Password:"
send "你的密码\n"
interact

spawn sudo hexo d
expect "Password:"
send "你的密码\n"
interact

再创建一个脚本去执行上面的两个脚本

schedule_commit_rep.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/bin/bash

export PATH=脚本存放路径:$PATH

repo_path="你的本地仓库地址"
blog_path="你的本地博客地址"

# 提交本地仓库
cd ${repo_path}
commit_repo.sh

# 提交blog
cd ${blog_path}
~/.blog_ssh-add.sh
exec_hexo.sh

执行效果

现在脚本已经准备好了,需要做的是加入定时任务

crontab

根据这篇文章OSX系统添加定时任务,可知macOS添加定时任务至少有两种方法,虽然作者推荐用launchctl,

这个是通过plist配置的方式来实现定时任务的,其优点就是最小时间间隔是一秒

但是这个优点在现在这个场景下并不重要,而且配置上比直接用crontab麻烦一些,因此还是选择用crontab来创建定时任务。

1
2
3
4
» ~ sudo crontab -e
Password:
crontab: no crontab for root - using an empty one
crontab: installing new crontab

进入创建新的计划任务的页面,并设置成每分钟都执行

1
* * * * * /bin/bash 脚本路径/.schedule_commit_rep.sh

等了好几分钟,似乎什么都没有发生,又找了两篇文章,说明了crontab的原理是

当用户使用crontab命令新建任务计划之后,该项 jobs 就会被 /var/spool/cron/ 目录下,而且以用户账号来创建一个文件,每一项任务计划为一行。
crond 检测的时间周期是 “分钟”, 每分钟会读取一次 /etc/crontab, 以及 /var/spool/cron 里面的记录并执行。
crond 执行的每一项任务计划,都会被记录到 /var/log/cron 这个日志文件。

另一篇说明的是在macOS上如何启用crontab,macOS*上默认没有/etc/crontab文件,用sudo touch /etc/crontab创建,等了几分钟后依然没有,查看了并没有spool/cron目录,在/var/log也没有*cron,macOS上的crontab与一般Linux上差别还是有点大。

搜索下stackoverflow,感觉比较近的is crontab broken on OSX El Capitan?,

指定编辑器?我使用crontab -l已经能看到了添加的计划任务了,感觉不太符合我的情况

我尝试了一下

1
*/5 * * * * date >> /tmp/z.date

确实是生成了,但是觉得并不能解决我的问题。好吧,换个思路吧,既然在macOS上推荐用launchctl,那就换个思路用它吧

launchctl

cd到家目录下的Library/LaunchAgents

1
» ~  cd /Users/Jason/Library/LaunchAgents

创建定时任务的plist描述文件,比如com.jason.launchctl.plist

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?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.jason.launchctl.plist</string>
<key>ProgramArguments</key>
<array>
<string>脚本路径.sh</string>
</array>
<key>StartCalendarInterval</key>
<dict>
<key>Minute</key>
<integer>30</integer>
<key>Hour</key>
<integer>22</integer>
</dict>
<key>StandardOutPath</key>
<string>脚本执行输出日志路径.log</string>
<key>StandardErrorPath</key>
<string>脚本执行错误日志路径.err</string>
</dict>
</plist>

参考以下指令启动定时任务

1
2
3
4
5
launchctl load   com.jason.launchctl.plist
launchctl unload com.jason.launchctl.plist
launchctl start com.jason.launchctl.plist
launchctl stop com.jason.launchctl.plist
launchctl list
  • 要让任务生效,必须先load命令加载这个plist
  • 如果任务呗修改了,那么必须先unload,然后重新load
  • start可以测试任务,这个是立即执行,不管时间到了没有
  • 执行start和unload前,任务必须先load过,否则报错
  • stop可以停止任务
  • ProgramArguments内不能直接写命令,只能通过shell脚本来执行

load,然后用start直接执行一下

已经在执行了,终于可以了。

但是发现提交博客输入密码那步停了,修改plist只执行提交blog*的那一步,发现.err*有内容,打开


我先试试把interact注释看影响操作不。

尝试后发现会影响,搜索后没有发现比较满意的解决方案,如何用expect配合launchctl实现定时任务,即该任务要自动输入密码?

我以为是zsh终端的关系,换成bash在终端下执行也没有问题,而用launchctl执行配置文件不管是bash还是zsh都一样报错。

解决方案

用写的脚本提交博客与本地工程,虽然无法定时的自动执行,但与以前相比效率还是稍微提高了一些的😔。

参考

UIView的init与initWithFrame:的调用关系 搭建Web服务器(nginx)
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×