摆脱瞎忙人生, 从自动化做起. 作为一名职场人, 有没有为忘发汇报邮件而烦恼过, 有没有因繁忙的工作而丢三落四过; 作为一名程序员, 有没为每天早上 pull 代码后漫长的编译时间而烦躁过, 有没有为各种无脑的系统配置而无聊过. 每天我们都在这些重复枯燥的事情中, 浪费着我们宝贵的生命. 如何提高工作效率成为我们至关重要的事情 , 这篇文件将会带领我们通过自动化的方式, 来有效地提高我们的工作效率.
本文大部内容是基于 MacOS 环境的, 非 Mac 党也可以借鉴其中的一些思想.
Shell Script
Shell 与 Shell Script
在谈自动化之前, 我们先来了解下 Shell Script 这门有点古老而又非常强大的脚本语言, 首先我们要分清一个概念性的问题, Shell 和 Shell Script 之间的区别:
Shell 是指一种应用程序, 这个应用程序提供了一个界面, 用户通过这个界面访问操作系统内核的服务.
Shell 脚本(Shell Script), 是一种为 Shell 编写的脚本程序.
这里先给大家科普下概念, 但大多的时候, 我们都统称 Shell Script 为 shell, 文中的其它地方的 "shell" 指的同样是 Shell Script. 关于 shell 的基础语法, 并不在本文的讨论范围内, 但在开始实践如何通过 shell 来提高我们工作效率之前, 我来我简单介绍 shell 几个常用而又强大的功能.
常用串联命令
管道
管道是 shell 中非常常用的功能之一, 它允许不同脚本, 命令之间互相传递数据, 例如:
ls | grep 'pars'
该命令意思是将 ls 输出的内容传递到 grep 'pars' 命令, grep 会把包含'pars' 的内容过虑出来. 我们再举个栗子, 通过 shell 获取 Git 仓库里中的当前分支名:
- currentBranch = `git branch | grep "*"`currentBranch = $ {
- currentBranch
- /*/}
- 重定向
- 大多数 UNIX 系统命令从终端接受输入并将所产生的输出发送回终端. 一个命令通常从一个叫标准输入的地方读取输入, 默认情况下是终端. 同样, 一个命令通常将其输出写入到标准输出, 默认情况下也是终端. 如果你需要修改输入或输出, 就需要使用到重定向功能.
- 命令 说明
- command > file 将输出重定向到 file。
- command < file 将输入重定向到 file。
- command >> file 将输出以追加的方式重定向到 file。
- 输出重定向, 指将一条命令的输入位置重新定义, 举个例子:
- ls> ls.txt
- ls 输出结果应显示在终端, 而上面命令将 ls 的输出结果写到 ls.txt 这个文件中. 需要注意, 用> 重定向到 ls.txt 文件默认是覆盖的, 如果需要用追加的方式写入文件, 则需要使用>>:
- pwd>> ls.txt
- 输入重定向:
- pbcopy <ls.txt
- 上面的命令的意思是, 将 ls.txt 的内容复制到粘贴板.
- 之所以简单介绍这几个常用功能, 是因为如果不懂这些功能, 会影响理解下面的内容. 如果你对 shell 脚本不熟悉, 建议你抽空学习一下, 日常工作中, 用到 shell 的频率还是非常高的.
- 实践是检验学习的唯一标准
- 简单聊完 shell 这几个常用而又强大的功能后, 我们开始实践如何通过 shell 来提高工作效率.
- 双网卡自动配置
- 因我日常工作的需要, 电脑需要配置双网卡, 这里以配置电脑的双网卡为例, 先附上部分配置脚本:
- inside_ssid=\"WIFINAME\";
- en0_ssid=\"$(networksetup -getairportnetwork en0 | sed's/.*[:] //')\"
- if [ \"$en0_ssid\" != \"$inside_ssid\" ]; then
- echo -n \"请先将内网卡设置到 $inside_ssid\"
- else
- inside_adaptor_index=\"$(netstat -rn|grep default |grep en0 -n | cut -d: -f1)\"
- if [ \"$inside_adaptor_index\" = 1 ]; then
- echo -n \"请开启外网卡, 且服务顺序在内网卡前 \"
- else
- inside_gateway=\"$(netstat -rn|grep default |grep en0|awk'{print $2}')\"
- sudo echo \"刷新配置成功 \";
- sudo route -n delete -net 10.*.*.128;
- sudo route -n delete -net 10;
- sudo route -n delete -net 30;
- sudo route -n add -net 10.*.*.128 $inside_gateway;
- sudo route -n add -net 10 $inside_gateway;
- sudo route -n add -net 30 $inside_gateway
- fi
- fi
- 这里不解析这些脚本的作用, 我们的重点在于如何进一步提高效率上. 由于每次重启电脑, 都需重新配置双网卡, 才能正常同时使用内外网, 也就是说, 每次重启电脑需要重新执行一次这个操作. 懒是人类的天性, 如果我们连执行一下脚本也不想干的话, 那么我们需要怎么做呢?
- 我们可以在在电脑开机时设置自启动任务. 首先我需要创建一个 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>LaunchOnlyOnce</key>
- <true/>
- <key>Label</key>
- <string>com.dengyonghao.xxxx</string>
- <key>ProgramArguments</key>
- <array>
- <string>/Users/xxxxx/work/Tools/xxxx.sh</string>
- </array>
- </dict>
- </plist>
- 简单解析下各个 key 的作用, LaunchOnlyOnce 指定开机后只执行一次, 不指定则每隔一段时间就会执行一次. Label 指定该 plist 的唯一标识. ProgramArguments 则是设置执行脚本的路径, 指向你想要启动时自动执行的脚本路径.
- 完成上面操作后, 把创建的 plist 文件拷贝到 ~/Library/LaunchAgents 目录下, 表示仅对当前用户生效, 然后执行:
- sudo launchctl load ~/Library/LaunchAgents/xxxxxx.plist
- 将这个文件注册到系统中, 然后电脑启动时就会自动执行, 完成双网上的配置. 这里有一个问题, 如果启动时自动执行上面的双网卡配置脚本, 真的能正常运行吗?
- 事实上是不行的, 因为 sudo 命令需要你输入管理员密码, 但你并没有地方输入, 所以是没有权限进行这些操作的. 故我们需要用到 Apple Script, 从而引出下一节的内容, 这里先附上 Apple Script 脚本:
- do shell script "inside_ssid=\"WIFINAME\";
- en0_ssid=\"$(networksetup -getairportnetwork en0 | sed's/.*[:] //')\"
- if [ \"$en0_ssid\" != \"$inside_ssid\" ]; then
- echo -n \"请先将内网卡设置到 $inside_ssid\"
- else
- inside_adaptor_index=\"$(netstat -rn|grep default |grep en0 -n | cut -d: -f1)\"
- if [ \"$inside_adaptor_index\" = 1 ]; then
- echo -n \"请开启外网卡, 且服务顺序在内网卡前 \"
- else
- inside_gateway=\"$(netstat -rn|grep default |grep en0|awk'{print $2}')\"
- sudo echo \"刷新配置成功 \";
- sudo route -n delete -net 10.*.*.128;
- sudo route -n delete -net 10;
- sudo route -n delete -net 30;
- sudo route -n add -net 10.*.*.128 $inside_gateway;
- sudo route -n add -net 10 $inside_gateway;
- sudo route -n add -net 30 $inside_gateway
- fi
- fi" with administrator privileges
- 这里只是用 Apple Script 来提供一个图形界面来要求用户先输入管理员密码, 才允许他继续执行脚本. 脚本使用了 Apple Script, 故开机启动项的 plist 的文件也要做相应的变化:
- <key>ProgramArguments</key>
- <array>
- <string>osascript</string>
- <string>/Users/xxxx/work/Tools/xxxx.scpt</string>
- </array>
- 关于 Apple Script 的内容将在下一节详细介绍, 这里我们先思考一个问题: 设置开机执行后, 就能解决上面说的痛点了吗?
- 事实上并不能解决所有问题, 比如说, 开机的时候外置网卡没有插上, 那么自动执行的脚本就会配置失败, 这时就又回到最初的场景, 需要我们去找到这个脚本文件, 然后通过终端执行. 那么我们可以怎么去优化这个流程呢? 我们带着这个问题, 继续后面的内容, 然后来再回来解决它.
- 集思广益
- 在给团队成员分享的过程中, 队友们提出 sudo 可以明文设置管理员密码, 不需要每次运行时手动输入, 命令格式如下:
- echo password | sudo -S xxxxxxxxx
- 需要注意的是, 明文保存密码存在泄露的风险, 建议使用这种方式前先评估风险.
- Apple Script
- Apple Script 是什么?
- AppleScript 是 Apple 创建的脚本语言, 用于自动执行 Macintosh 操作系统及其许多应用程序操作的语言. 可以用来控制运行于 macOS 上的程序, 以及 macOS 本身的部分内容. 你可以创建脚本来自动执行重复性任务, 或组合多个可编写脚本的应用程序的功能来创建复杂的工作流程.
- 我们使用 AppleScript 创建备忘录, 管理网络, 处理图像, 备份文件等等, AppleScript 是功能非常强大的自动化工具, 它内置于 macOS 系统中, 通过 脚本编辑器 应用来编写和运行, 任何用户都可以免费使用它.
- 脚本编辑器
- macOS 中默认已经提供编写 AppleScript 的工具: 脚本编辑器, 我们可以通过应用程序中找到并启动它.
- 我们第一个 AppleScript 脚本
- 我们打开脚本编辑器并选择新建文稿, 输入以下内容:
- tell application "Finder" to open the startup disk
- 点击运行后, 系统会在桌面打开一个新的 Finder 窗口, 显示启动盘的内容, 这里我们已经完成了第一个 AppleScript 脚本.
- 再举个栗子, 通过 AppleScript 打开或者关闭 Xcode:
- tell application "Xcode"
- activate
- --quit
- end tell
- 从上面脚本可以看出, AppleScript 和自然语言非常接近, 编写起来十分简单, 但至于如何去学习 AppleScript 的语法, 这里不会多做讲解, 有兴趣的同学可以通过官方文档学习.
- 如何学习 AppleScript
- 巧用文档
- Dash, 程序员神器之一, 强烈推荐一波.
- 我们在学习一门新的编程语言时, 当在使用某个 API 遇到问题时, 最靠谱的解决方法不是 Google, 而是先看下它的文档 . 我们可以通过 Dash 下载 AppleScript 文档, 遇到问题时, 我们可以快速查阅, 并且 AppleScript 的文档并不多, 空闲时可以通读一次(估计 2-3 小时), 逐步加深对 AppleScript 的了解.
- 读懂 AppleScript 词典
- 实践出真知
- 汇报邮件提醒 & 自动生成
- 下面我们直接开始实操, 来实现一个自动提醒发送重点项目进度的工具, 除了提醒功能外, 该工具还会自动帮你创建邮件模块, 包括收件人, 主题, 内容模板等, 我们来看实现脚本:
- on callback()
- tell (current date) to get (its year as integer) & "-" & (its month as integer) & "-" & day
- set dataText to the result as text
- set mailTitle to "- 重点项目进度" as text
- set mailTitle to dataText & mailTitle
- tell application "Microsoft Outlook"
- set newMessage to make new outgoing message with properties {subject:mailTitle, content:"Dear xx:<br/>以下是我的重点项目进度情况, 详细请查看附件:<br/><br/><br/>Best Regards"}
- make new recipient at newMessage with properties {email address:{name:"xxx", address:"xxxx@pingan.com.cn"}}
- #make new cc recipient at newMessage with properties {email address:{name:"Name", address:"test@example.com"}}
- open newMessage
- end tell
- end callback
- display dialog "又到周一了, 赶紧发重点项目进度" buttons {"现在发", "一会发"} default button 1
- if the button returned of the result is "现在发" then
- callback()
- end if
- 这里我们通过 AppleScript 访问 Microsoft Outlook 并自动生成邮件模板, 以上脚本只给邮件内容填充了模块, 但实际上还可以实现自动把你的重点项目进度 Excel 统计表附件进来, 再进一步的话, 可以直接通过 AppleScript 读取 Excel 的内容, 然后填充到邮件内容中, 只要你在完成重点项目内容后, 及时更新 Excel 统计表中的内容, 那么到每周一发重点项目的时候, 你只需要一个命令就可以自动完成汇报邮件.
- 我们完成了自动生成邮件模板的功能后, 还需提供自动提醒的功能, 关于自动提醒功能, 我们可以使用 Mac 的启动服务来实现, 和自动配置双网上的方式一模一样, 我们创建相应的 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.dengyonghao.viproject</string>
- <key>ProgramArguments</key>
- <array>
- <string>osascript</string>
- <string>/Users/dengyonghao/work/Tools/viproject.scpt</string>
- </array>
- <key>StartCalendarInterval</key>
- <dict>
- <key>Weekday</key>
- <integer>1</integer>
- <key>Minute</key>
- <integer>30</integer>
- <key>Hour</key>
- <integer>10</integer>
- </dict>
- </dict>
- </plist>
- 需要注意的是这里多了 StartCalendarInterval 这个 key, 这个 key 是用来控制你脚本的执行周期或者时间的, 这里设置为每周一上午 10:30 时就会自动执行脚本.
- AppleScript 的内容就简单介绍到这里, 总之 AppleScript 非常强大, 具体怎么使用, 建议空闲时共同探讨一下.
- 推荐阅读
- Mac Automation Scripting Guide
- Automator
- Automator 是什么?
- Automator 是苹果公司为 macOS 系统开发的一款软件, 只要通过点击拖拽鼠标等操作就可以将一系列动作组合成一个工作流程, 从而帮助你自动的 (可重复的) 完成一些复杂的工作. Automator 实际上是一些列动作组合在一个工作流文档里, 然后按顺序去执行这些动作, 与我们上面所以说的脚本非常类似, 但 Automator 可以横跨多个程序进行, 并提供图形界面进行操作, 用户操作起来非常方便.
- 脚本转应用
- 关于 Automator, 我们可以通过实现脚本转应用的例子进行了解, 首先我们打开 macOS 自带的 Automator, 选新建文稿 -->应用程序 -->实用工具 -->运行 xxx 脚本, 然后把你的脚本填写进去, 然后保存生成一个应用. 生成的应用默认是 Automator 的图标, 如果你想去改变图标, 则可以右击应用 ->显示包内容 -->Contents-->Resources, 然后把 AutomatorApplet.icns 替换成你想要的图标就可以了.
- 我们可以把常用的脚本生成应用, 放到常用的位置, 双击一下就能执行, 这样也是挺爽歪歪的, 但是这并不是我想要的, 我想在任意的地方法都可以快速执行, 所以这里就引入了 Alfred 这个工具了.
- 推荐阅读
- 关于 Automator 网上有不少教程, 想进一步了解的同学, 推荐阅读: Automator 简单介绍及入门玩法 | Matrix 精选 https://sspai.com/post/36667
- Alfred & WorkFlows
- Alfred 是什么? 可能只能说是神器, 不吹不黑, 但这里我是不会讲如何去使用 Alfred 的, 没有用过的小伙伴自行百度.
- Workflow 又是什么梗呢, Workflow 工作流的意思, 它表示把多个事件联合在一起, 形成一个连贯的动作.
- 自我学习
- 这里省略成千上万的字, 需要你自行去学习 Alfred 的使用, 或许它 --> Google 可以帮你
- 问题回顾
- 讲到这里, 我们可以思考下文章开始配置双网卡的那个问题, 估计大家都会有更好的方法了.
- 我们可以把配置双网卡的 AppleScript 写成 Alfred 的一个 workflows. 比如我设置了 Alfred 的快捷打开键为 double com, 双网上配置 workflows 的 keyword 为 doublenet, 这样的话, 我可以在电脑的任意界面输入: double com + doublenet + 回车, 即可完成双网卡的配置.
- 一锅乱炖
- 上面介绍了一堆的工具, 看到这里, 可能还是一脸懵逼, 现在我们来通过实操, 来把它们一锅炖了.
- Goto iTerm
- 作为一名程序员, 从 Finder 目录跳转到 iTerm 的场景非常多, 大多数时候我们都是通过拖动目录到 iTerm, 然后 cd 进去, 效率非常低, 通过学习上面的内容, 我们可以通过 AppleScript + Hotkey 快速在 iTerm 中打开当前 Finder 的目录.
- 首先我们可以通过 AppleScript 获取当前 Finder 窗口的目录:
- tell application "Finder"
- set pathFile to selection as text
- set pathFile to get POSIX path of pathFile
- -- 防止目录存在空格跳转不了
- set pathFile to quoted form of pathFile
- end tell
- 然后通过 iTerm 提供的 AppleScript API 跳转到指定目录:
- ell application "Finder"
- set pathFile to selection as text
- set pathFile to get POSIX path of pathFile
- -- 防止目录存在空格跳转不了
- set pathFile to quoted form of pathFile
- set pathFile to "cd" & pathFile
- --set the clipboard to pathFile
- tell application "iTerm"
- create Windows with default profile
- tell current session of current Windows
- write text pathFile
- end tell
- end tell
- end tell
- 我们完成脚本后, 则可以通过 Alfred 配置一个 Hotkey, 用来快速执行该脚本:
- 我这里面配置的 Hotkey 是 com + T, 所以我只要按下 com + T, 则会自动打开 pwd 在当前 Finder 窗口的目录下的 iTerm.
- 速记大法
- 每次开周会时, 在一周回顾环节中, 总是拼命回顾这周我做了那些事情, 特别是分享亮点和不足的时候, 就各种词穷. 这里介绍一个非常有效的方法, 就是每天记一记, 周会不纠结. 其实这个方法大家都知道, 只是大家都懒得记, 或者是没有找到一个好的工具, 我曾经用印象笔记记录过一段时间, 但用了一段时间后, 发现每当脑子突然灵光一闪, 有好的 idea 并想记录下来时, 然而印象笔记并没有打开, 接着自己又懒得打开来记录了. 为了避免再次发生这种事情, 我通过 notes + applescript + alfred 来实现一个速记事情工作流:
- on alfred_script(q)
- tell application "Notes"
- tell account "iCloud"
- tell (current date) to get (its year as integer) & "-" & (its month as integer) & "-" & day
- set dataText to the result as text
- set mailTitle to dataText & "- 速记"
- make new note at folder "PANote" with properties {name:mailTitle, body:q}
- end tell
- end tell
- end alfred_script
- 这段 applescript 的意思是把 alfred 获取到内容, 保存到 PANote 文件下. 现在我们实现了快速记录的功能后, 我们还需要快速来查找, 我们也是通过 applescript + alfred 来实现:
- use framework "Foundation"
- property NSRegularExpressionSearch : a reference to 1024
- property NSString : a reference to current application's NSString
- property NSJSONSerialization : a reference to current application's NSJSONSerialization
- property NSUTF8StringEncoding : a reference to current application's NSUTF8StringEncoding
- on run argv
- set output to {}
- tell application "Notes"
- set folderNames to name of folders in default account
- repeat with folderIndex from 1 to number of folders in default account
- set folderName to item folderIndex of folderNames
- if folderName is "PANote" then
- set currentFolder to (a reference to item folderIndex of folders in default account)
- set noteIDs to id of notes of currentFolder
- set noteNames to name of notes of currentFolder
- set noteBodies to body of notes of currentFolder
- repeat with i from 1 to count of noteIDs
- set noteBody to (NSString's stringWithString:(item i of noteBodies))
- set noteBody to (noteBody's stringByReplacingOccurrencesOfString:"<[^>]*>|
- "withString:" "options:NSRegularExpressionSearch range:{0, noteBody's |length|()})
- set noteBody to (noteBody's stringByReplacingOccurrencesOfString:"^ +| +$| +(?= )|"withString:"" options:NSRegularExpressionSearch range:{0, noteBody's |length|()}) as text
- set match to (item i of noteNames) & "" & folderName &" " & noteBody
- if length of noteBody is Less than 100 then
- set subtitle to noteBody
- else
- set subtitle to text 1 thru 100 of noteBody
- end if
- set subtitle to folderName & "|" & subtitle
- set end of output to {title:(item i of noteNames), arg:(item i of noteIDs), subtitle:subtitle, match:match, uid:(item i of noteNames)}
- end repeat
- end if
- end repeat
- end tell
- set output to {|items|:output}
- set output to NSJSONSerialization's dataWithJSONObject:output options:0 |error|:(missing value)
- set output to (NSString's alloc()'s initWithData:output encoding:NSUTF8StringEncoding) as text
- return output
- end run
- 这里的代码看起来非常多, 其实原理非常简单, 首先遍历 default account 下的所有文件夹, 然后找到 PANote 这个文件夹, 把查找到的内容格式化后传给 output,alfred 会帮我们把 output 的内容以列表形式展示出来. 当我们选中展示中的内容时, 我们还需要在 Notes 里面打开相应的内容, 故我们再实现一个打开 Notes 的脚本:
- on alfred_script(q)
- tell application "Notes"
- show note id q
- end tell
- end alfred_script
- 需要注意的是, 这个方法 id 参数是从上一段代码中的:
- output to {title:xxxx, arg:xxxx, subtitle:xxxx, match:xxxx, uid:xxxx}
- arg 里面获取的, 这个是 alfred 定义的格式, 我们无须关心他是如何实现的, 只要按照 alfred 的规范来传参就可以了.
- 自动拉代码并编译
- 每天早上我到公司的时候, 首先是去洗杯打水, 然后拉代码编译, 接着等待漫长的编译时间, 日复一日, 风雨无阻~~ 但在某个发呆的瞬间, 突然有一个想法, 为啥不让系统在我到公司前把代码编译好呢, 我到公司的时候就可以直接工作, 不用等待漫长的编译过程了.
- 有了这种想法, 就要动手去做, 我们把任务一步步地拆分, 首先是拉代码, 在拉代码前, 我们需要先检查仓库是否干净, 然后默默写下以下脚本:
- checkGitWorkspaceClean() {
- echo "Action - checkGitWorkspaceClean"
- if [ $# -lt 1 ]; then
- echo "One param is required - the check dir.";
- exit 1;
- fi
- if [ ! -d $1 ]; then
- echo "The dir does not exist - $1";
- exit 1;
- fi
- currentDir=`pwd`
- cd $1
- result=`git status -s`
- if [ -n "$result" ]; then
- echo "The git workspace is not clean - $1"
- exit 1
- fi
- cd $currentDir
- }
- 这里通过 Git status -s 命令来判断当前仓库是否是可拉取代码状态, 如果不可拉取就直接退出.
- 接着下一步是拉取当前所有分支的最新代码, 我们需要获取分支名并拉取该分支的最新代码:
- pullLatestCode() {
- echo "Action - pullLatestCode"
- if [ $# -lt 1 ]; then
- echo "One param is required - the check dir.";
- exit 1;
- fi
- if [ ! -d $1 ]; then
- echo "The dir does not exist - $1";
- exit 1;
- fi
- currentDir=`pwd`
- cd $1
- currentBranch=`git branch | grep "*"`
- currentBranch=${currentBranch/*/
- }`git pull git pull--rebase origin $ {
- currentBranch
- }`cd $currentDir
- }
有没有觉得这些代码很熟悉, 其实在 shell 那节都有介绍过的, 这里只是把上面说的内容应用到实际的场景中而已.
拉取完成代码后, 我们就可以通过 xcodebuild 编译代码, xcodebuild 参数可以参考 apple 官方帮助文档, 这里你默认使用模拟器进行编译:
- buildProject() {
- echo "Action - pullLatestCode"
- if [ $# -lt 1 ]; then
- echo "One param is required - the check dir.";
- exit 1;
- fi
- if [ ! -d $1 ]; then
- echo "The dir does not exist - $1";
- exit 1;
- fi
- currentDir=`pwd`
- cd $1
- xcodebuild -workspace ${PARS_PROJECT_NAME}.xcworkspace -scheme ${PARS_PROJECT_NAME} -sdk iphonesimulator build
- cd $currentDir
- }
这样我们整个拉取和编译流程都可以通过代码来实现了, 但是在编译代码前, 应该先检查下仓库是否有冲突, 如果有冲突就不开始编译, 所以正确的流程是:
- checkGitWorkspaceClean $PARS_PROJECT_DIR
- pullLatestCode $PARS_PROJECT_DIR
- checkGitWorkspaceClean $PARS_PROJECT_DIR
- buildProject $PARS_PROJECT_DIR
当不能正常完成编译时, 可以通过 AppleScript 显示一些可视化的提示, 比如弹窗之类的, 这一些优化依据个人习惯添加就可以, 不过多讲解.
如果你觉得在终端编译不够直观, 无法直接看到编译进度, 我们则可以通过 AppleScript 来优化代码编译流程, 直接调用 Xcode 来编译或者运行代码:
- tell application "Xcode"
- open "/Users/xxxxx/xxxx/xxxxx/xxxxx.xcworkspace"
- set workspaceDocument to workspace document "xxxxx.xcworkspace"
- repeat 120 times
- if loaded of workspaceDocument is true then
- exit repeat
- end if
- delay 1
- end repeat
- if loaded of workspaceDocument is false then
- error "Xcode workspace did not finish loading within timeout."
- end if
- set actionResult to run workspaceDocument
- repeat
- if completed of actionResult is true then
- exit repeat
- end if
- delay 1
- end repeat
- end tell
到这, 已经把最关键的拉取和编译代码的功能讲完, 至于如何定时执行, 在上文已经详细介绍过, 这里不重复讲解. 但是定时任务存在一个不太方便的问题, 就是当你电脑关机或者休眠时, 这个定时任务就不会启动. 设置电脑一直待机不休眠也不太好, 毕竟公家财产也是要爱护的, 比较折中的方法是把这个脚本写成 alfred 的 workflows, 我们到公司时, 可以先花 1-2 秒时间来执行这个 workflows, 然后再去洗杯打水吃早餐之类的, 等你把乱七八糟的事情搞定了, 代码也快编译好了.
集思广益
在给团队成员分享的过程中, 队友们就自动拉代码并编译时机方面, 提出了更好的方案: 每天晚上 12 点 (大家都下班的时候) 时执行脚本, 执行完成后通过脚本让电脑休眠, 从而避免电脑长时间待机.
总结
本文简单分享如何通过工具, 来处理日常工作中遇到的一些烦琐的事情 , 通过使用脚本等方式来实现自动化, 从而提升个人的工作效率. 这里仅提供一个思路和一些例子, 至于如何发挥, 就得看你自己如何去使用这些工具了, 总之, 工具是越用越合手的.
我的小专栏 https://xiaozhuanlan.com/topic/9205763184 , 如果喜欢, 可以订阅一波.
来源: https://juejin.im/post/5bfac61ee51d454af013a900