过去N年都上推太多,过去一年总想限制自己上twitter的时间,让工作效率提高起来,但时常看着 rescuetime.com/dashboard 的 social network 类别当日使用时长超过一小时(我给自己定的上推时长阈值),依然停不下看推发推的步伐。。。 最近借着内部和外部多种因素,写了个限制发推时段的脚本,现在把方法和经历总结一下。
要做的是: 限制在制定的时段内,twitter.com不能在电脑上访问,无论客户端还是browser。系统环境是Mac OS X 10.7,随便想了几种方案,决定用crontab加bash script修改/etc/hosts文件中twitter的api/stream/search地址来完成操作。
首先,/etc/hosts 文件中添加如下三行
127.0.0.1 api.twitter.com
127.0.0.1 search.twitter.com
127.0.0.1 stream.twitter.com
这时候twitter就无法访问了。然后写一个bash脚本,根据当前时间,确定在上面的几行内容最前部前添加或者去除注释符号来完成启用或者禁用封锁twitter的功能。脚本blocktwitter.sh内容如下
#!/bin/bash
HOUR=`date "+%H"`
BLOCK=0
if [ "$HOUR" -ge 9 -a "$HOUR" -lt 12 ]; then
BLOCK=1
fi
if [ "$HOUR" -ge 13 -a "$HOUR" -lt 18 ]; then
BLOCK=1
fi
if [ "$BLOCK" -eq 1 ]; then
#echo "block twitter"
sudo sed -i -e \
"s/^#127.0.0.1 \(.*\).twitter.com/127.0.0.1 \1.twitter.com/g" \
/etc/hosts
say "Now blocking twitter"
else
#echo "unblock twitter"
sudo sed -i -e \
"s/^127.0.0.1 \(.*\).twitter.com/#127.0.0.1 \1.twitter.com/g" \
/etc/hosts
say "Now unblocking twitter"
fi
"$HOUR" -ge 13 -a "$HOUR" -lt 18表示如果时钟小时数大于等于13并且小于18,这个可以根据需要进行调节(脚本中的时间是我司上班时段:)最后,使用
sudo crontab -e
命令编辑root用户的定时任务。在编辑器中添加
0 * * * * /bin/bash /Users/username/shell/blocktwitter.sh
行尾一定要有换行/回车。表示每小时的第0分钟执行/Users/username/shell/blocktwitter.sh脚本。这样,每小时检查并根据策略执行一次启用或者禁用twitter域名封锁的禁推脚本就完成了。
注意:最初不知道为何我试验crontab的时候总是执行不到脚本内容;后来经过不知是偶然还是必然的一次修改尝试,我把最后一个定时条件/最后一个星号(*)和执行命令(/bin/bash)之间的空格换成了TAB(制表符/0x09)就一切OK了,后来因为时间所限(其实是懒!)没有查证了,有空和好奇心的童鞋可以探究一下,可以告诉我下结论。还有就是crontab可以(有些是必须)添加SHELL/PATH/MAILTO环境变量,否则有些脚本中的功能会执行不了。
本文中还是有一些说得不够细致,也还有功能不足之处,不过这些细节和补充都是可以google到的,我也是一边google一边写完了这个脚本,不带debug奇怪问题的话也就半个小时就完成了这个功能,大家有什么更多需要更好的主意,尽情地自己扩展吧:)
我推特 https://twitter.com/kcome :)
从这次开始,把一些技术技巧记录也写在blog里,否则对我这种写博拖延症来说,保持一定频率真太难了。。。拖延症其实都是coding或者干活强迫症造成的,干活强迫症有点让我其他什么都进行困难了。。。废话少说,正题开始,这是一个条件略有复杂和奇特的case,需求可能有些和别人的不同,之前没有搜到特别完美的方案,就把自己的脚本以及折腾过程记录下来。
全程仅用Autormator里添加一个“Run AppleScript”任务,任务中有不少“do shell script xxx”的语句调用命令行工具。代码如下
on run {input, parameters}
set REMOTEIP to do shell script ¬
"curl -s http://11.22.33.44:8080/showip | grep -Eo \"([[:digit:]\\.]+)\""
do shell script "sed -i -e \"s/.* remoteIP.local/" & REMOTEIP & ¬
" remoteIP.local/g\" /etc/hosts" with administrator privileges
do shell script "dscacheutil -flushcache"
do shell script "route -n add -static " & REMOTEIP & ¬
" 192.168.2.1" with administrator privileges
tell application "System Events"
tell current location of network preferences
set VPNservice to service "VPN NAME IN SYSTEM PREFERENCES"
if current configuration of VPNservice is not connected then
connect VPNservice
repeat while current configuration of VPNservice is not connected
delay 1
end repeat
end if
end tell
end tell
do shell script "route -nv add -net 192.168.0.0/24 10.0.0.2" ¬
with administrator privileges
return input
end run
其中“¬”是OPTION+ENTER/RETURN,只是将太长的单行语句折行方便显示用的。
curl -s http://11.22.33.44:8080/showip | grep -Eo "([[:digit:]\\.]+)"
因为暴露远程网络IP地址的静态页面显示的并非一个单独的IP地址,这里用grep把其他无用信息过滤掉,将被扒光的IP地址付给变量REMOTEIP
do shell script "sed -i -e \"s/.* remoteIP.local/" & REMOTEIP & ¬
" remoteIP.local/g\" /etc/hosts" with administrator privileges
我再解释一下上面这行。因为远程网络的IP地址不固定,而Mac OS X里PPTP VPN的目标IP地址目前没有找到好方法用命令行或AppleScript修改,所以这里采用的方法是填写一个本地主机名“remoteIP.local”,然后在 /etc/hosts 文件中写入 “11.22.33.44 remoteIP.local”,这样就避免了在AppleScript或命令行下修改VPN连接目标IP的需求。这个方法虽然有点迂回和龌龊,但是其他更便捷的方法还没发现。缺点还包括每次连接vpn都要修改hosts文件,洁癖表示接受起来鸭梨略大。
route命令是让VPN连接走指定网关的。我是一开机即连上美国VPN的并设置为全局路由,而这里又希望连接办公网络的PPTP VPN不经过美国VPN,就指定了直接从网关经过。
下面的VPN连接代码应该是很容易可以google到的,到处都有解释这里就不多说了。
注意一点是如果命令行操作需要sudo,只需要去掉它并在do shell script “bla bla bla”后加“with administrator privileges”即可。虽然简单的东西也找了挺久,不知道是我不会找还是AppleScript文档比较囧。
其他就没什么了把。先到这里吧:)