Pages

Friday, 30 June 2017

这盛世,如你所愿

不知不觉,已是2017,你仍在这个城池。
有个玩搏击的青年看不下去太极大师们的作秀,轻轻一推徒弟,人就触电般的飞了出去,开始怒喷太极,终于有个雷公敢应战,几秒过后被KO,徐晓冬打假成功,却在几天内武馆被查,微博被封。
都说大自媒体时代让信息扁平,你却能看到弹指一挥间就让他再也没有任何渠道发声,仿佛这个人从来没存在过,人们渐渐淡忘。反太极是反中国武术啊,这是反中华传统文化的重要组成部分,伤害了中国人民的感情,影响我国国际交流的符号,动摇民族复兴之梦。于是电视继续有公然造假的比武和神技,懒得遮掩,但大家已经明白,没有人再站出来了。
不知不觉,已是2017,你仍在这个城池。
北电女大学生被校园潜规则性侵爆出,一天就刷爆了网络。出来鸣不平的是受害女生的学弟侯亮平,爆出很多黑幕。然后很快,微博再也看不到他的信息,想必是他在一个接一个新账号被封之后已经放弃。接着是北影官微发了‌‌“该生自中学起就有抑郁症,大学曾抑郁,自杀洗胃,他说的情况不存在.特此辟谣。‌‌”
组织已经决定了,你来当精神病。
几天之后一切归于平静,渐渐淡去。
不知不觉,已是2017,你仍在这个城池。
有天你在电视上看综艺,大张伟的头发全程特效,因为有新规定,禁止艺人染发,正如永久封杀吸毒艺人,整顿一下风气避免教坏小孩子。整顿着整顿着,你发现平常爱看的几个娱乐公众号也全没了消息,一些歌曲不能再留言评论,一些艺人消失了,一些文章不见了了,刷bilibili上传自拍生活记录也要实名认证了,连地产公众号竟然都封了(是呢,房价一说多了又挨删)。
2002年中日邦交正常化30周,日本乐队GLAY在北京演出,甚至被接见到中南海,日本前首相细川护熙逐一介绍完乐队成员后问‌‌“接见金发的日本人还是第一次吧?‌‌”
他回复道:‌‌“这样的造型也不错。‌‌”
不知不觉,已是2017,你仍在这个城池。
你担心以后怎么用Google scholar查论文,Gmail留学申请,上YouTube看最新的音乐艺术短片,用facebook和外国青年交朋友。这时候你还在打王者荣耀的小表弟凑过来看了一眼你手机上的google,问这是什么搜索引擎,那一刻你知道了或许自己多虑了呢,下一波人也许不需要用百度,soso,360之外的搜索引擎了呢。
微博上突然都在热议B站、微博等视频内容被广电总局整改,你起初也没在意。直到在朋友圈看到几家官方大号发的推送,注意到里面的评论区全是支持赞同的叫好声。而且运营官方大号的人也很懂新媒体,回复很逗挣得10w+,也会用流行语和漫画,再微博打架挂人的时候一呼百应。
曾经你刷知乎都是干货,即使对历史和国内外现状有不同看法可以讨论,现在再上去,你会发现还留在那里写文章的大V,都熟谙些什么风向的文字才能拿最多的赞,你本想顺手在一片赞扬里写下一条评论:‌‌“你们是花钱雇的水军吗?‌‌”然后你又删了,因为你知道,是你老了,这就是现在的新知乎用户和发自肺腑的小粉红留言,都是不需要花钱雇的。
不知不觉,已是2017,你仍在这个城池。
杭州有对夫妻,家境殷实,有三个可爱的孩子,幸福美满。后来保姆偷家里的财物,怕被发现于是纵火企图毁灭证据,女主人和三个孩子被烧死,丈夫出差回来,悲痛欲绝。
所幸这次穷保姆太可恶了,没有出现“你穷,你有理”的情况,网上舆论没有再像以前仇富(谁还记得上次留美普通学生买个二手宝马遇害被指责富二代死了活该),只有零星的人感慨中国的阶层固化和贫富差距。
受害者的亲人责问物业,说第一时间赶到的时候,保安先是说里面没人,后来又拦着不让上去,消防栓没水,破门不让进去救人说需要等审批。最后真的人没了,死在你面前却不能去救。丈夫已经是买得起几千万豪宅的人,仍是盛世中的蝼蚁,只能跪在小区门口向物业讨说法,维权困难重重,热搜被撤,诉求被压,媒体报道的焦点是模糊的。
不知不觉,已是2017,你仍在这个城池。
甘肃省临夏回族自治州的清真寺了一座又一座,三千座清真寺的验证了信仰的虔诚,广河县奢华的清真寺与质朴的小学对比,全州在财政自给仅6%、贫困人口多达90多万的情况下,克服困难修建寺庙。
与此同时,因为相关政策倾斜领不到救济而被迫毒死自己四个子女后服毒自杀的该县汉族村民杨改兰去世不满一年。
不知不觉,已是2017,你仍在这个城池。
六岁打球,十五岁入队,世界冠军,大满冠得主,退役后坚守球队,带着中国乒乓球队确立了无可撼动的地位。突如其来的降职,内情在上头允许两方都可发声的情况下再写吧。
令人感动的是门徒世界第一马龙,世界第二樊振东,世界第三许昕选择赌上荣誉和前途退赛,然后你看到了‌‌“社会影响不好要严肃处理‌‌”,下面支持教练和球员的留言和转发,又是陆续已删除。有人戏说现在日本队的想法是‌‌“金国喜闻大宋斩了岳飞‌‌”。
有大V预言一周之内肯定会道歉,第二天一早你出了门,想起昨晚上的愤慨,有些恍惚。下班路上暴雨瓢泼,你打着伞艰难地淌过水,好不容易到了目的的,这时你拿出手机刷新闻——中国乒乓球队集体发布道歉声明。
不知不觉,已是2017,你仍在这个城池。
这是最好的时代,这是最坏的时代,这是智慧的时代,这是愚蠢的时代,这是信仰的季节,这是怀疑的季节,这里直通天堂,这里直堕地狱。——狄更斯
你小心翼翼地在网上表达自我,可是你发现总会有关键字发不出去,于是不得不用谐音或者代称夹杂着符号才能写完一段完整的话。每天在深夜,你看到一个个思想的烟花绽放,虽然灼眼却又令人神往。
天一亮,到了上班时间,整个世界再次恢复一切美好,没有任何刺眼的光芒。偶尔你会想骂那个上班天天删东西的人,可又转念一想,他不也是拿着微薄工资撑着下去的苦人吗,或许在工作之外的现实生活中,他受到不公和欺负不比你少,他也会无力矛盾彷徨的面对这个世界。
不知不觉,已是2017,你仍在这个城池。
其实写到这里,我不知道写这篇文章的意义。因为即使朋友圈刷屏,仍然会很快的被忘记。不信,我问问你,谁还记的前阵子热议的北大赴美交流硕士章莹颖女士失踪一案?到现在仍然没有破案,而且找到的几率越来越小。
或许我们真的可以活的轻松一点,因为除了你的父母至亲,对你的成败和生死比较关心以外,真的没多少人在乎你,别把自己看得太重。即使你离去,三个月后不会有任何人一直念叨你,一切归于平静。也请你只跟最好的人分享你的喜悦吧,他们不会嫉妒。
有人嘲笑美国的警察办案能力很低,而且美国没有遍布的摄像头可以随时锁定犯罪车辆,反观我国的摄像头早已能够全程监控,现在已经有了面部识别功能。
如果失踪案发生在中国24小时之内就破了,只要社会足够关注,一如我们帮助外国友人找丢失的自行车和钱包只是分分钟的事。如果不够重视,就会像郜艳敏那样,N多年后被拐女成为山村女教师,颁发一个最美感动人物。
只是我想问谁应该被认真对待?为什么人大校友雷羊被打死了才能全民关注,北大的学生失踪才会牵动这么多人心,那么考不上一本的芸芸众生怎么办?
不知不觉,已是2017,你仍在这个城池。
又到夏季,到日本旅游的高峰又到了,大家淡忘了APA酒店否认南京大屠杀的事件,还记得当时APA社长元谷外志雄拒不道歉,绝不撤掉辱华书籍,声称中国人忘性大,几个月后又会排队来送钱。
可不可以不那么容易漠视和淡忘?今年是2017年,离第一次网上掀起声讨杨永信的热潮已经过去了7年,可是又有什么变化呢?依然排队送钱送孩子去,也许家长和杨永信都不傻。
来看看本质吧,中国现在很多城乡结合部或者留守儿童家庭没有学历、时间、精力和沟通能力教育好孩子,而封建的家长对孩子又有控制欲。只要孩子不按照自己的意志和设计的路线,都可以认为是不孝,命都是我给的,你就得听我的这么走。
年少一点不准看电视不准上网赶紧考高分,长大一点赶紧繁殖恋,赶紧回家乡将来好养老。管他玩网游还是玩手游还是二次元还是赌德州扑克都可以作为一个噱头来指控这孩子因为这个学坏了,得治治。
杨永信能提供这样的产品,家长需要这样的产品,即使大家都知道戒网瘾学校里面侵犯权益、剥夺自由,他们不心疼。当父母竟然不需要资格审查、孩子自选就可以当,世界上最可怕的事。出厂之后是一个多么孝顺听话的产品啊!
清楚本质之后其实很简单,完全可以开一个更加体面的正能量大学校,温水煮青蛙加上蜜糖和美好叙事,孩子本人不但没有任何不适反而挺开心,还觉得自己和家庭将来要走向人生和世界巅峰。换了个方式,最终你还是按照家长希望你有的那种脑子进化着。
不知不觉,已是2017,你仍在这个城池。
每次总有好像很成熟的过来人说,不如闷声发大财,写什么写。我知道对方并不是没有过理想,并不是一开始就这么现实或犬儒主义。
他一方面也有同样的感慨,一方面又失去说话的动力,当你写下他潜意识里想说却根本不敢说的话时,安全感和自尊心收到了破坏,让他自惭形秽,所以他才那么热衷于笑话那些说话的‌‌“傻子‌‌”,这样他才能心安理得的继续麻木下去。
眼睛一闭一睁,你好像到了2046年。你的孩子问着你关于这些他不能理解的一切,你回答不上,你们仍在这个城池.

又一个ios下的Shadowsocks客户端程序-夜莺

快速智能的 Shadowsocks,HTTP(S), Socks5代理工具.

将网络请求数据道理到指定服务器,提高传输速度,保护传输数据安全.

官网:http://go.playstone.org/

让自建的HTTPS proxy server支持 wingy

自己搭建的https代理服务器在ios中的wingy里面不可用,
原因是wingy不太遵循常规https代理协议,它实现的HTTP连接和HTTPS都是默认用的CONNECT方法,这样也就是禁用了squid的缓存功能

并且默认CONNECT的端口都是80,而恰巧的是squid的默认最小化配置中,没有开启CONNECT的80端口;

解决方法就是修改squid.conf文件

在这句[acl SSL_ports port 443]的上面添加

acl SSL_ports port 80

即可解决。

目前自己建的HTTPS proxy server已经支持 wingy。
 
如何搭建https代理服务器,见这里:http://briteming.blogspot.com/2015/08/squidchrome.html

断网生存指南

有没有想过,如果有一天突然全国范围内断网,你该怎么办?
据中国互联网络信息中心(CNNIC)在2016年下半年发布的第38次全国互联网发展统计报告,中国网民人数已达7.1亿,互联网普及率已达51.7%。如果一个外星人由于飞船故障迫降在中国,他会惊奇的看到城市街头的每一个人都盯着手上的奇怪设备(手机),通过无线信号将千里之外的服务器上的信息抓取到小小的手持设备上,如饥似渴的吸吮着互联网的信息流,同时不停的上传新的内容,每个人消费和生产的数据在网络运营商处汇聚成一望无际的比特海。
这个外星人很可能像杨永信一样对『网络』这玩意有着耿直的理解,认为每个低头族都让未来分外危险,而断了全中国的网才是善莫大焉。他判断地球已经进入了『紧急状态』,于是毫不犹豫的按下了那个红色按钮———
一瞬间,你被断网了。
焦躁的你发现信号满格、路由器正常、网线也并没有被猫拔掉,怎么就突然断网了呢?尝试过无数种方法的你最终会认清这个无奈的事实——网实实在在的断了,所有IP和端口都被屏蔽,没有任何方法可以使你连接到曾经无远弗届的互联网。
但出于某些不可知的原因,外星人并没有从物理上摧毁所有骨干网。得知这个消息的你欣喜若狂,你深知这个发现的重大含义——即便互联网已无法访问,但每个人的电脑实际上还是互相连接的。换句话说,你们仍处于同一个巨型局域网之中,甚至仍有公网IP。所以,理论上,通过某种方式,你或许能再度利用那些被荒废的网线和电缆?
从抽屉里掏出了一只崭新的U盘,你拍了拍它,轻声说了句——『那么,拯救世界的任务就交给你了!』
无服务器、永远在线的网站——ZeroNet
网址:https://zeronet.io/
ZeroNet是一个免费、开源、使用Bitcoin加密技术和BT技术的全平台分布式网络工具,他的原理比较像我们熟悉的BT下载:当我们通过种子(torrent)下载电影和音乐时,这些资源的来源并非某个机房中的服务器,而是其他用户的电脑硬盘,只要在网络中还存在任何一台电脑『做种』,资源就能够被持续下载,同时提供资源的设备量也会迅速增长,因此BT下载无法被单点封禁。
ZeroNet的工作原理与BT大致相同。在你通过ZeroNet搭建一个网站后,处于同一个网络中的用户即可通过ZeroNet将你的网络论坛下载到他的硬盘里,同时进行浏览。当第三个用户访问这个站点时,你和第二个用户会同时向他上传网站。如果用户基数足够大,那么即便你的电脑关机甚至硬盘损坏,只要别人的电脑上仍保存有网站的文件,这个网站就能永远『存活』下去。是不是很酷?
目前ZeroNet提供论坛、博客、社交网站、加密邮件、即时聊天等,几乎覆盖了大多数的互联网服务。在断网时期,网民实际上有能力以极低成本来为彼此搭建这些基础服务。不仅如此,ZeroNet还可以通过Tor网络隐藏自己的身份,ZeroNet绝对是你对抗外星人的工具包中的一件利器!

断网后我们照样聊天——Tox
网址:https://tox.chat/
Tox是一个开源免费的分布式加密通讯协议,诞生于『棱镜计划』被斯诺登曝光之后,对用户的通讯内容进行端到端加密,中间不经过任何中央服务器,还可以用于局域网内通讯。你发给好友的聊天内容不会像其他聊天软件一样先发送到中央服务器、再转发给收件人,而是直接发送到目标用户。
Tox和ZeroNet一样,也使用了BT技术,将用户点对点的连接起来。在你使用Tox的时候,会生成一个独一的用户名,只要你的朋友知道你的用户名,即可开始聊天。
目前Tox已经支持全平台,并有很多版本的客户端,界面简单易用不需要复杂配置,绝对是逃离外星人监控、实现安全通讯的不二选择!

虽然断网,但我还有几个G的学习资料想传给远方的你——Resilio Sync
上文介绍的ZeroNet和Tox都依赖BitTorrent公司开发的BT技术,其实BitTorrent公司自己也有一套黑科技——Resilio Sync。
Resilio Sync是一个分布式同步工具,同样不需要服务器,且支持全平台(但并不开源)。当你把一个文件夹加入Resilio Sync中时,可以生成一串密钥,如果在另一台设备的Resilio Sync中输入该密钥,就能将你的文件夹远程同步到这台设备中。之后加入的所有同步节点,都可以在下载资源的同时向其他用户上传资源。
由于文件存储在本地硬盘而非服务器上、对传输内容进行了加密、又以BT基础为依托,Resilio Sync实际上是一个高安全度、无存储空间限制、无下载流量限制、无审查、无法被封杀的超级网盘。资源拥有者甚至还可以通过设置权限来控制资源的分发和更改。例如你和你的朋友希望分发你们的音乐专辑,那么你可以分配给他读写权限,然后将只读权限通过各种方法公开出去,此时你们二人可以远程协作共同编辑专辑,而其他网友则可自由下载,当文件被修改的时候,所有同步节点都会被更改。
Resilio Sync还有很多很强大的使用方法,发挥想象力,它能成为对抗外星人的制胜法宝!
从你把包含了以上三个工具的U盘插入电脑的那一刻开始,这个看似被外星人判了死刑的网络就又有了重生的希望。你会把这些工具传递给别人,然后他们传给更多人。从古代开始,人们就懂得利用点对点的『飞鸽传书』来通讯,今天你们只不过把鸽子变成了一个个字符,传递到每一台电脑上。只要鸽子足够多,网络不仅会以另一种形态复苏,还能爆发出更强大的力量。
所以断网以后,不要放弃网络!!

Thursday, 29 June 2017

利用七牛云,备份网站数据

将备份文件保存在VPS环境中,一旦服务器崩溃或者被删除,我们的数据又会消失不见;或者我们每天通过FPT等方式将数据传回本地进行保存,但是比较麻烦。
那我们何不继续利用脚本的方式将数据保存到对象储存呢?
目前,阿里云,腾讯拥有对象储存业务,而且价格不是一般站长能承受。所以还是推荐使用七牛云。用户注册即送10G的永久免费空间,对于一般的博客足够使用了。需要实名认证才能送免费空间,介意请绕道。

准备七牛云空间

1.打开—-七牛云官网,注册账户;
2.完成实名认证,很简单,通过支付宝授权,很快就完成认证的;
3.新建储存空间,并设置为私有空间(公开和私有仅对 Bucket 的读文件生效,修改、删除、写入等对 Bucket 的操作均需要拥有者的授权才能进行操作);
4.七牛账户下,个人中心—->密钥管理,记录AccessKey和SecretKey,供qshell鉴权使用。

VPS备份配置

qshell  说明文件
注:以下脚本都存放于data目录,即/data/
1.请根据VPS的实际情况,下载对应版本的qshell并上传至至VPS的data目录
qshell_linux_386—-Linux 32位系统
qshell_linux_amd64—-Linux 64位系统
qshell_linux_arm—-Linux ARM CPU
qshell_darwin_amd64—-Mac 64位系统
配置qshell   (linux)
cd /data       #打开data文件夹
ls      #查看qshell是否存在
mv qshell_linux_amd64 qshell        #将对应版本的qshell文件修改文件名为qshell
vi ~/.bashrc        #将qshell加入环境变量中,使其能够在任何位置都可以执行
编辑文件并在底部添加        export PATH=$PATH:/data    #路径即为qshell所在的文件夹
chmod +x qshell        #赋予qshell可执行权限
qshell account AccessKey SecretKey       #为qshell的上传至七 牛云功能鉴权

在data目录下新建LocalUploadConfig.json文件,编辑文件并在文件中添加如下内容:
{
   "src_dir"            :   "/home/backup/try",    #本地同步路径,为全路径格式,工具将同步该目录下面所有的文件
   "bucket"             :   "YouB",    #同步数据的目标空间名称,可以为公开空间或私有空间
   "ignore_dir"         :   false,    #保存文件在七牛空间时,使用的文件名是否忽略本地路径,默认为false
   "overwrite"          :   true,    #是否覆盖空间中已有的同名文件
   "check_exists"       :   true,    #每个文件上传之前是否检查空间中是否存在同名文件
   "check_hash"         :   true,    #在check_exists设置为true的情况下生效,是否检查本地文件hash和空间文件hash一致
   "check_size"         :   true,    #查看本地文件和空间文件大小是否一致
   "rescan_local"       :   true,    #检测新增文件
   "skip_file_prefixes" :   "test,demo,",    #跳过所有文件名(不带相对路径)以该前缀列表里面字符串为前缀的文件
   "skip_path_prefixes" :   "hello/,temp/",    #跳过所有文件路径(相对路径)以该前缀列表里面字符串为前缀的文件
   "skip_fixed_strings" :   ".svn,.git",    #跳过所有文件路径(相对路径)中包含该字符串列表中字符串的文件
   "skip_suffixes"      :   ".DS_Store,.exe",    #跳过所有以该后缀列表里面字符串为后缀的文件或者目录
   "log_file"           :   "upload.log",    #上传日志的输出文件,如果不指定会输出到qshell工作目录下默认的文件中,文件名可以在终端输出看到
   "log_level"          :   "info",    #上传日志输出级别,可选值为debug,info,warn,error,默认info
   "log_rotate"         :   1,    #上传日志文件的切换周期,单位为天,默认为1天即切换到新的上传日志文件
   "log_stdout"         :   false    #上传日志是否同时输出一份到标准终端,默认为false,主要在调试上传功能时可以指定为true
}
测试上传并应用于生产环境
qshell qupload 1 /data/LocalUploadConfig.json    #单线程上传本地备-份文件至七-牛云的对象储存的储存空间
待上传完成后,打开七牛云账户,查看文件是否完全上传,是否出错等。一切正常后,配置每天自动上传。
crontab -e    #编辑自动执行脚本
添加运行脚本        0 4 * * * /data/qshell qupload 1 /data/LocalUploadConfig.json
配置qshell (WINODWS)
执行qshell需要的命令
cd C:/qrsbox

qshell account AccessKey SecretKey

建立bat文件,给计划任务使用
@echo off
cd C:/qrsbox
qshell qupload 10 qshell.conf
pause
在c盘qrsbox目录下创建qshell.conf文件
{
   "src_dir"            :   "C:\\webbak",
   "access_key"         :   "111111111",
   "secret_key"         :   "222222",
   "bucket"             :   "",
   "zone"               :   "nb",
   "ignore_dir"         :   false,
   "up_host"            :   "http://up-z0.qiniu.com",
   "overwrite"          :   true,
   "check_exists"       :   true,
   "check_hash"         :   false,
   "check_size"         :   false,
   "skip_file_prefixes" :   ".git,bin",
   "skip_fixed_strings" :   ".svn",
   "skip_suffixes"      :   ".DS_Store,.exe,.config,.log",
   "rescan_local"       :   true,
   "log_file"           :   "upload.log",
   "log_level"          :   "info"
}
然后执行BAT文件看看效果...

npm install之冗余依赖

我们知道,npm3把所有依赖模块路径拍扁了(工程目录下的node_modules出现了很多package.json中没有声明的模块),解决了windows下路径名过长的问题,更使得公共依赖被充分共享。但如果多个模块依赖了同一个模块的不同版本,后安装的模块,为了不和别人冲突,就只能将这个依赖安装在自己的node_modules下。
这个问题来源于我们实际某个基于VueJS的复杂项目的某次意外,为了使广大前端更容易理解,我们使用jquery作为栗子。
假设,我们用webpack开发一个小页面,需要用到jquery和一个jquery插件(假设叫jplugin)。假设这个jquery插件,遵循了ES6规范,它的package.json声明依赖的jquery版本是^2.0.0(即>=2.0.0, <3.0.0):
1
2
3
4
5
{
"dependencies": {
"jquery": "^2.0.0"
}
}
它的主模块,应该会有类似这么几句:
1
2
3
4
5
import $ from 'jquery'
$.fn.jplugin = function () {
// 插件代码
}
而我们的项目直接依赖的jquery版本是^1.11.0(即>=1.11.0, <2.0.0):
1
2
3
4
5
{
"dependencies": {
"jquery": "^1.11.0"
}
}
很明显,^2.0.0^1.11.0并不能兼容。那么,在npm i之后,依赖目录大致是这样的(无关文件已省略):
1
2
3
4
5
6
7
8
.
├── node_modules
│   ├── jquery // ^1.11.0, 假定安装的是1.11.0版本
│   └── jplugin
│   ├── node_modules
│   │   └── jquery // ^2.0.0,假定安装的是2.0.0版本
│   └── package.json
└── package.json
我们的主模块代码应该会有类似这么几句:
1
2
3
4
5
6
import $ from 'jquery'
import 'jplugin'
// 其他代码
$('#someId').jplugin()
最终运行代码,浏览器会报错,提示jplugin不是一个function,也就是$('#someId').jplugin()这句出错。
为什么呢?
webpack打包依赖时,与node查找依赖的方式一致,顶级依赖写法(比如这里的jquery)首先从当前目录的node_modules下查找,如果不存在,则向上级目录的node_modules 下查找,如果不存在则继续向上,以此类推。
在我们这个例子里,jplugin模块本身查找到的jquery版本是2.0.0,在这个2.0.0jquery上才会存在jplugin这个扩展。而我们的主模块查找到的jquery版本是1.11.0版本,在这个1.11.0版本的jquery上调用jplugin就出错了。
说到这里,还并没有引出本文的主题,不过也能够解释依赖版本冲突导致发生奇怪问题的现象了。
继续这个例子,当我们发现版本依赖有问题时,我们要处理它。假设我们把项目直接依赖的jquery升级到2.0.0,并不会导致其他兼容问题,我们执行npm i jquery@2.0.0 --save. 我们看一下现在的目录结构:
1
2
3
4
5
6
7
8
.
├── node_modules
│   ├── jquery // ^2.0.0,假定安装的是2.0.0版本
│   └── jplugin
│   ├── node_modules
│   │   └── jquery // ^2.0.0,假定安装的是2.0.0版本
│   └── package.json
└── package.json
上层的jquery已经升级到2.0.0了。我们很兴奋的再次运行页面,发现仍然还是报同样的错。
其实问题的原因是一样的,虽然大家都是2.0.0版本的jquery,但 此jquery非彼jquery,大家拿到的并不是同一个jquery对象。
其实,此时只要把根目录的node_modules删除,再次执行npm i,看看最终的目录结构:
1
2
3
4
5
6
.
├── node_modules
│   ├── jquery
│   └── jplugin
│   └── package.json
└── package.json
如此一来,大家拿到的就是同一个jquery对象啦,最后页面运行正常了~
这个问题,才是本文要说的 依赖冗余 的问题,即,曾经由于依赖冲突导致安装了同个模块的多个版本,修正依赖版本后,再次npm i,仍然解决不了问题,删除全部node_modules重新安装依赖才正常。遗憾的是,npm并没有这么聪明,或者有其他原因,并没有在安装新模块后,自动帮我们梳理依赖关系。
那么,遇上这样的问题,就只能删除全部依赖彻底重新安装一次依赖吗?有没有更优雅的方式?
答案是npm dedupe(或简写npm ddp).
这个命令会重新计算所有依赖关系,把可以公用的依赖上升到顶级node_modlues,并删除底层不必要的 副本。注意,需要整理的模块越多,所花的时间也越长。
因此,建议在你的构建过程中添加此命令,从而避免这种问题的发生。
ps: npm update命令也同样存在此问题。
ps: 在写这篇文章之前,google到 玩转npm 这篇文章, 蛮有参考价值,建议阅读.
-----------------------

玩转npm

npm本来是Node.js的包管理工具,但随着JS这几年的蓬勃发展,现在的npm已经成了几乎所有跟JS相关的工具和软件包的管理工具了,并且还在不断发展完善中。
本文从笔者的经验,总结了npm安装/卸载、更新、发布这几个最主要功能的正确使用姿势和一些小技巧,顺便从官网搬来了npm3处理依赖的重大变化。

npm3

npm团队已经发布了npm3,近期有小伙伴吐槽npm3安装软件包的时候很慢,一开始笔者也感觉相比npm2慢了不少,但经过了几个版本的迭代,速度似乎又快起来了。
慢的同学是时候更新你的npm啦,而且之前安装进度条模糊成一坨的问题也已经修复了。
npm v3.0安装react的截图
npm 3.0
npm v3.8安装react的截图
npm 3.8
npm提供了大量的命令,所有的命令几乎都可以通过npm cmd [options]的方式使用。

npm -h

学习一个命令行工具,最简单直接的方式就是查看它的用户手册,npm提供了并不算很详细的命令行手册,可以通过npm -h查看(unix用户还可以通过man npm查看,相对来说比windows详细多了),需要某个npm命令更详细的文档则需要通过npm help cmd如npm help install来查看,注意不是 npm install help ,这样将会安装help包。
另外npm cmd -h也是一个快速查看命令可以怎么使用和搭配哪些常用选项的方法。

npm init

说到npm就不得不说package.json,每一个npm包都必须有一个package.json文件,年轻时候的我还傻乎乎的从其他地方拷贝package.json过来然后修改,为了自动化还写了个自动生成的脚本。
后来才发现原来npm自带此功能,官方原厂功能更好更强大,只需要执行npm init即可,以交互方式完成package.json的创建。
如果想生成默认package.json,可以执行npm init -y,连交互式界面都不会出现。
另外需要注意,npm init的时候需要输入用户字段,如果还没有设置npm用户,需要通过npm addUser设置。
事实上,最小单位的npm包就是只包含一个package.json文件的包,这样的话npm init就完成了一个npm包的创建。

npm install/uninstall

npm install作为npm最重要的功能和最常用的功能,不用过多说明,这里只介绍三个非常有用的选项–global,–save,–save-dev。
想必读者肯定知道–global可以简写成-g,其实另外两个选项也有简写形式,–save可以简写成-S,–save-dev可以简写成-D,注意大写。
另外npm install也可以简写成npm i,相应的卸载命令npm uninstall可以简写成npm un,事实上npm的很多命令和选项在设计上都非常类似unix上的命令行功能,这里指的是命令和选项都可以极大化地简写,只要在不混淆的情况下。
npm uninstall和npm install接受同样的选项和参数。
–save的作用是在packaje.json的dependencies字段增加或者修改一个安装包和版本号名值对,–save-dev则是修改devDependencies,这样就不用安装了某个包之后手动修改package.json,npm已经帮我们把包依赖和版本管理做好了。
以安装react为例,
npm i react -S将为package.json增加
npm i react -D将增加

npm update

假如react@15(版本号,下同)发布了,想尝鲜的小伙伴该怎么更新呢?
首先得知道npm上是否已经更新,npm info react可以查看到react在npm上发布过哪些版本以及最新的版本,但是内容太多,让人眼花缭乱,配合grep会好一些。
其实我们只想知道react最新的版本,使用npm dist-tags ls react直接列出react发布过哪些tag,
以及这些tag目前最新是哪些版本,比如最常用的latest,也是默认tag。
next tag已经发布了react@15的第一个rc版了,尝鲜的朋友可以试一试了。
另外一个命令npm outdated,会检测当前安装的所有npm包是否有更新,并列出可以更新的包,如果没有任何输出,那么恭喜你,所有的包都是不需要更新的。
如果之前安装的react版本是0.14.3,同时还安装了redux@3.2.0,执行npm outdated会输出
这种情况则说明react和redux该更新了,更新具体某个包使用npm update package_name即可,npm update则会更新所有可更新的包。

npm publish

npm作为一个大仓库,每天都有大量的新包发布上来,发布自己的包非常容易,而且几乎零门槛,对应的发布的命令是npm publish,但前提是你需要一个npm账号。
假设已经有账号了,在发布之前需要使用npm login进行登录,正式发布之前请先阅读以下关于版本号的介绍。
npm包的版本号一般都是x.y.z的形式。
其中x表示主版本号,通常有重大改变或者达到里程碑才改变;
y表示次要版本号,或二级版本号,在保证主体功能基本不变的情况下,如果适当增加了新功能可以更新此版本号;
z表示尾版本号或者补丁号,一些小范围的修修补补就可以更新补丁号。
第一版本通常是0.0.1或者1.0.0,当修改了代码,需要更新版本号重新发布到npm,不知道的小伙伴(年轻的我)肯定会手动修改package.json的version字段,而高级的玩法是直接使用npm version <update_type>命令自动搞定。
详细用法可通过npm help version查看,这里只介绍最常用的三种。
三个选项分别对应三部分的版本号,每次运行命令会导致相应的版本号递增一,同时子版本号清零。
如果npm包同时又是一个git仓库,在运行了npm version <update_type>和npm publish之后,npm会自动给git仓库打上一个跟当前版本号一样的tag,对于挂在github上的npm包很有用。

npm2 & npm3

上面介绍了npm包安装/卸载、更新和发布,几乎能满足日常使用了,另外再搬点干货过来。
npm3虽然慢,但解决了windows上npm包目录太深的问题,相信使用过npm1或者npm2的都知道,node_modules太多太深了,甚至一不小心就超过windows资源管理器能处理的最长路径长度了,听起来有点拗口,说白了这时候复制粘贴删除就会报错了。
已经使用过npm3的肯定会发现,npm3将依赖模块扁平化存放了,node_modules文件夹里面子文件夹增多了,出现了很多没有通过npm install安装过的模块。
npm3在安装包的时候,由于每个包和包的依赖都会去计算是否需要再安装,搜索起来确实变慢了,好在至少现在的npm3速度还是可以接受的。
按照官方文档介绍,npm3处理模块依赖的方式跟npm2很不一样。
以下是从官网搬的砖

npm的依赖

假如我们写了个模块App,需要安装两个包A@1和C@1,其中A@1依赖另一个包B@1,C@1依赖B@2,用npm2和npm3安装之后的依赖图分别是这样的
npm3dependencies
npm3按照安装顺序存放依赖模块,先安装A@1,发现依赖模块B@1没有安装过也没有其他版本的B模块冲突,所以B@1存放在第一级目录,B@2为了避免和B@1的冲突,还是继续放在C@1之下。
npm2没什么好说的,来什么安装什么,根本不用理会公共依赖关系,依赖模块一层一层往下存放就是了,下面重点讲解npm3在这方面的改进。
现在App又需要安装一个包D@1,D@1依赖B@2,使用npm3安装之后,包结构将变成下面这样
npm3dependencies-1
虽然C@1和D@1都依赖B@2,但是由于A@1先安装,A@1依赖的B@1已经安装到第一级目录了,后续需要安装的所有包B,只要版本不是1,都需要避免和B@1的冲突,所以只能像npm2一样,安装在相应包下面。
接着又安装了一个E@1,依赖B@1,因为B@1已经安装过,且不会有版本冲突,这时候就不用重复安装B@1了,包结构会变成这样
npm3dependencies-2
随着App升级了,需要把A@1升级到A@2,而A@2依赖B@2,把E@1升级到E@2,E@2也依赖B@2,那么B@1将不会再被谁依赖,npm将卸载B@1,新的包结构将变成这样
npm3dependencies-3
可以看到出现了冗余,结果跟预期的不一样,既然所有对B的依赖都是B@2,那么只安装一次就够了。

npm dedupe

npm在安装包的时候没有这么“智能”,不过npm dedupe命令做的事就是重新计算依赖关系,然后将包结构整理得更合理。
执行一遍npm dedupe将得到
npm3dependencies-4
这才是最优且符合预期的结构,看来在每次安装/卸载了包之后最好重新执行npm dedupe,以保证包结构是最优的。
npm3通过将依赖模块扁平化安装,避免了冗余又解决了windows上一大头疼问题。
原创文章转载请注明:
转载自AlloyTeam:http://www.alloyteam.com/2016/03/master-npm/

日本的人均预期寿命为83.7岁,为全球之冠

相比之下美国的人均预期寿命为79.3岁,而中国的人均预期寿命则为76.1岁。在新生儿死亡率方面,日本的新生儿死亡率为2.17‰,远低于英国的4.5‰和美国的5.2‰,而中国的这一数据为8.1‰。(以上数字均为2015年数据)
看完这些关乎每个普通人生存质量的数据,你还会觉得作为世界第三大经济体,人类发展指数极高的当代日本是个“三流国家”吗?

Mac 设置指南


如何配置一个高效的 Mac 工作环境

English Version

Table of Contents

  1. OS X
  2. 常用工具
  3. 开发工具
一直想写这么一篇文章,把我从同事那里学到的经验分享出来。市面上有很多类似的文章,写得都非常好,让我受益匪浅。不过我还是有一些自己总结出来的经验想要分享。
在工作中,我一般会在 1 到 10 人的团队中,经常会结对编程,即两个人共用一台 Mac 工作,因此也经常会把 Mac 外接一个大显示器、鼠标和键盘。我的常用开发平台有 Java、Ruby、Node.js、Web 等,使用 JetBrains 的开发工具,比如 IntelliJ IDEA、RubyMine、WebStorm 等。
我深知自己的知识有限,所以写下本文以便和大家切磋交流。同时更有效率的方法和更好的工具也在不断涌现,我也贪心的希望把更好的方法和工具都收集更到到这里,我会不断更新本文,让它尽量不过时。最新内容请访问:https://github.com/macdao/ocds-guide-to-setting-up-mac。欢迎通过 GitHub 的Issues或者直接Pull Requests方式来分享你的经验。期待你的反馈。
我认为“一个高效的 Mac 工作环境”有以下几个特点:
  • 自动化
    举个例子。手动安装一个应用,需要1)打开浏览器,2)搜索应用的名字,3)打开应用网站,4)寻找下载链接和安装方法,5)下载并等待下载完成,6)安装下载文件,7)可能还有后续的安装步骤。而自动化安装一个应用,只需要1)打开终端工具,2)敲入安装命令,3)等待完成这几个步骤。
    自动化可以大大简化操作,提高效率。
  • 统一
    我经常结对编程,偶尔会遇到快捷键不一样,命令不同等问题。我强烈建议,至少在一个团队中,大家尽量使用相同的快捷键、命令等环境。(我记得有个实践就是这个,可是我一直没找到该实践的名字和出处,求告诉)
  • 够用
    够用就好,如果系统本身已经满足了我的需求,我不会再使用第三方工具。
  • 效率
    效率,一切都是为了效率。
本文对于第三方应用如何安装和使用只有最简单的介绍,具体还请参考官方网站和相关文档。
有些章节标题标注了[OCD],意思是这些章节带有我强烈的个人色彩,如果你跟我臭味相投,欢迎借鉴,如果你并不认同,请忽略掉好了。
PS:虽然本文名为“强迫症”,但其实并不是真正意义上的强迫症,真正意义上的强迫症是一种会对患者的日常生活产生负面影响的疾病。

1. OS X

本节介绍操作系统本身的一些设置。

功能键

默认情况下,F1-F12 都是特殊功能,比如调节屏幕亮度。而当你需要键入 F1-F12 时(比如在使用 IntelliJ IDEA 的快捷键时),需要同时按住 Fn。这对于开发人员来说是非常不方便的。
把 F1-F12 改成标准功能键:选择System Preferences > Keyboard,在Keyboard标签页中选中Use all F1, F2, etc. keys as standard function keys

全键盘控制

当你在 Sublime Text 里关闭文件时,可能会遇到这样的对话框:
dialog-box-without-all-controls
注意这个Save按钮跟其他两个按钮不太一样,它的底色是蓝的。这种按钮被称为默认按钮,除了用鼠标点击触发外,还可以通过回车键触发。
那么问题来了,如果你不想保存,想点击Don't Save,是不是只能用鼠标点击了呢?
并不是这样:选择System Preferences > Keyboard,在Shortcuts标签页中选择All controls;或者使用快捷键⌃F7。之后这个对话框会变成这样:
dialog-box-with-all-controls
这个Don't Save按钮有了一圈蓝边,这个意味着你可以通过空格键触发。不仅如此,你还可以用Tab键把蓝边转移到其他按钮,来实现全键盘控制。
除了All controls这个方法,你还可以用⌘⌫来选择Don't Save⌘⌫的作用是在包含“删除”或“不存储”按钮的对话框中选择“删除”或“不存储”。
除了上述两个办法之外,居然还有个方法!就是按⌘D!据说是因为按⌘+按钮的大写首字母可以触发该按钮。可是!我按了⌘C⌘S想取消和保存都没用!但是⌘D真的有用!如果仅仅是这也就算了,可是我又手贱试了下 TextEdit,在关闭未保存的文件时弹出的对话框上有三个按钮DeleteCancelSave。然而⌘D⌘C都没用,但是!⌘S可以保存!我完全不能理解!我整个人几乎都是崩溃的,只好以咆哮体写下这段文字。如果谁能解释请务必告诉我,必有重谢!
⌘C不能用应该是因为它绑定到了复制功能;而⌘D不能用因为它的作用是从“打开”对话框或“存储”对话框中选择“桌面”文件夹。
在这个对话框上,你可以用Esc来执行Cancel操作。

Spotlight 快捷键

中文版 OS X 的 Spotlight 的快捷键是⌃Space。这个快捷键有一些问题:
  • JetBrains 的 IDE,比如 IntelliJ IDEA、WebStorm 等都使用⌃Space作为自动完成这个最常用功能的快捷键。我不建议更改 IDE 的快捷键,而建议更改 Spotlight 的快捷键。
  • 对于没有添加中文输入法的 Mac 来说,Spotlight 的快捷键是⌘Space。英语国家的人都是这样的。所以我建议把 Spotlight 的快捷键设置为⌘Space,跟他们一致。

输入法快捷键

一般来说切换输入法的快捷键是⌘Space。由于我建议把 Spotlight 的快捷键设置为⌘Space,所以我建议把切换输入法的快捷键设置为⌥Space

其他快捷键

让双手尽量多的键盘和快捷键,少使用鼠标和触摸板,可以大大提高效率。

设置 Trackpad 轻点来点按

默认情况下按下触摸板才是点按(click)。我喜欢设置成用轻点作为点按:
选择System Preferences > Trackpad,在Point & Click标签页中选中Tap to click

语音

OS X 自带了语音功能,可以用say命令让 Mac 开口说话:
say hello
可以和&&或者;配合使用来提示你某任务已经完成:
brew update && brew upgrade && brew cleanup ; say mission complete
通过命令行来听取发音还是有点麻烦。其实我们几乎可以在任何地方选中单词,然后使用快捷键⌥+ESC发音。仅仅需要这样设置一下:选择System Preferences > Dictation & Speech,在Text to Speech标签页中选中Speak selected text when the key is pressed

词典

OS X 自带了词典(Dictionary)。你几乎可以在任何应用中通过三指轻拍触摸板来现实对应单词的释义。
也可以打开 Dictionary 应用来查找单词。
可以在 Dictionary 应用中添加英汉汉英词典。

Dock Position

默认 Dock 在屏幕下方。我们的屏幕一般都是 16:10,Dock 在屏幕下方的话会占据本来就不大的垂直空间。建议把 Dock 放到左边或者右边。

更改 Caps Lock 键为 Control 键

我经常用到Control键,但这个键在键盘的左下角,很难按到。同时我发现我很少使用Caps Lock键,我一般会用Shift键加字母来输入大写字母,或者先输入小写再(通过快捷键)转换成大写。
基于以上原因,我把Caps Lock键的功能改成了Control键。很多同事也都这么做的,可能是受到 HHKB 的影响。
设置方法:选择System Preferences > Keyboard,在Keyboard标签页中点击Modifier Keys...按钮,在弹出的窗口中,把Caps Lock (⇪) Key:对应的选项改成⌃ Control

Remove all Dock icons[OCD]

本条目对于强迫症适用。
默认情况下 Dock 被一堆系统自带的应用占据着,而其中大部分我都很少使用,当我打开几个常用应用后,Dock 上会有很多图标,每个图标都会被挤得很小。所以我会把所有 Dock 上固定的图标都删掉,这样一来 Dock 上只有我打开的应用。
PS:Finder 图标是删不掉的。
除了一个一个删除图标,也可以通过这个命令来隐藏所有的固定图标:
defaults write com.apple.dock static-only -boolean true; killall Dock
恢复也非常简单:
defaults delete com.apple.dock static-only; killall Dock
PS:使用这个方法的话,Dock 上的Downloads也会被隐藏掉。

重置 Launchpad 上图标位置[OCD]

本条目对于强迫症适用。
新的应用被安装后,经常会跑到 Launchpad 的第一屏,所以它们的位置跟安装的顺序有关系,而我更希望它们可以按照某种更加稳定的顺序排列,比如按照系统默认的顺序:
defaults write com.apple.dock ResetLaunchPad -bool true; killall Dock
在默认顺序中,Launchpad 第一屏只有 Apple 自家应用。

创建大小写敏感的工作区

在多人合作的项目开发时,因为 Mac 文件系统默认是大小写不敏感的,所以经常会出现一些诡异的问题。创建一个大小写敏感的工作区(workspace)来解决避免这些问题:
hdiutil create -type SPARSE -fs 'Case-sensitive Journaled HFS+' -size 100g -volname workspace ~/Documents/workspace.dmg.sparseimage
可以通过三种方式挂载镜像:
  1. 直接双击打开 ~/Documents/workspace.dmg.sparseimage
  2. open ~/Documents/workspace.dmg.sparseimage
  3. hdiutil attach ~/Documents/workspace.dmg.sparseimage

Keychain Access

钥匙串访问(Keychain Access)是一个 OS X 应用程序,对我来说它最大的功能就是查看已经保存的各种账号和密码,包括 Wi-Fi 密码。

2. 常用工具

本节介绍一些常用的,跟开发没有直接关系的第三方应用及其设置。

Homebrew

包管理工具,官方称之为The missing package manager for OS X
安装步骤见官网。
有了 brew 以后,要下载工具,比如 MySQL、Gradle、Maven、Node.js 等工具,就不需要去网上下载了,只要一行命令就能搞定:
brew install mysql gradle maven node
PS:安装 brew 的时候会自动下载和安装 Apple 的 Command Line Tools。
brew 的替代品有 MacPorts,现在基本没人用它。

Homebrew Cask

brew-cask 允许你使用命令行安装 OS X 应用。比如你可以这样安装 Chrome:brew cask install google-chrome。还有 Evernote、Skype、Sublime Text、VirtualBox 等都可以用 brew-cask 安装。
brew-cask 是社区驱动的,如果你发现 brew-cask 上的应用不是最新版本,或者缺少你某个应用,你可以自己提交 pull request。
安装步骤见官网。
应用也可以通过 App Store 安装,而且有些应用只能通过 App Store 安装,比如 Xcode 等一些 Apple 的应用。App Store 没有对应的命令行工具,还需要 Apple ID。倒是更新起来很方便。
几乎所有常用的应用都可以通过 brew-cask 安装,而且是从应用的官网上下载,所以你要安装新的应用时,建议用 brew-cask 安装。如果你不知道应用在 brew-cask 中的 ID,可以先用brew cask search命令搜索。

iTerm2

iTerm2 是最常用的终端应用,是 Terminal 应用的替代品。提供了诸如Split Panes一群实用特性。它默认的黑色背景让我毫不犹豫的抛弃了 Terminal。
安装:
brew cask install iterm2
感谢 brew-cask,我们可以通过命令行自动安装 iTerm2 了。
在终端里,除了可以用⌃E等快捷键(详见其他快捷键)之外,还可以使用⌥B⌥F等快捷键(具体可以参考这里)。前提是这样设置一下:
选择Iterm菜单 > Preferences > Profiles,选择你在使用的 Profile(默认是Default),在Keys标签页中把Left option (⌥) key acts asRight option (⌥) key acts as都设置成+ESC
在打开新的窗口/标签页的时候,默认情况下新窗口总是 HOME 目录,还需要我每次敲命令才能进入工作目录。如果想要这个新窗口在打开的时候就自动进入工作目录,需要如下设置:
选择Iterm菜单 > Preferences > Profiles,选择你在使用的 Profile(默认是Default),在General标签页中的Working Directory部分中选择Reuse previous seesion's directory
至此,Terminal 应用已经出色的完成了其历史使命。后面命令行就交给 iTerm2 啦。
在 iTerm2 中双击会自动选中对应的词,三击会选中对应的整行。选中的内容会自动进入剪贴板,不需要再按⌘C复制。

Oh My Zsh

默认的 Bash 是黑白的,没有色彩。而 Oh My Zsh 可以带你进入彩色时代。Oh My Zsh 同时提供一套插件和工具,可以简化命令行操作。后面我们会看到很多介绍,你会看到我爱死这家伙了。
安装方法见官网。
目前我使用的插件有:git z sublime history rbenv bundler rake
Oh My Zsh 使用了 Z shell(zsh),一个和 Bash 相似的 Shell,而非 Bash。
在 Z shell 中,~/.zshrc是最重要的配置文件。Oh My Zsh 在安装的时候会把当前环境的$PATH写入~/.zshrc中。这并不是我期望的行为,因为使用了 brew,我们基本不再需要去定制$PATH,而 Oh My Zsh 提供的默认$PATH$HOME/bin:/usr/local/bin:$PATH是非常合适的一个值,它把$HOME/bin加入了$PATH,可以让我们把自己用的脚本放到$HOME/bin下。
所以建议把~/.zshrc重置:
cp ~/.oh-my-zsh/templates/zshrc.zsh-template ~/.zshrc
2016年6月17号的一次提交后,zshrc.zsh-template就不再修改$PATH了。请找到# export PATH=$HOME/bin:/usr/local/bin:$PATH这一行,把前面的#去掉。
Oh My Zsh 还有很多有价值的插件
替代品有 Oh My Fish。基于 Fishshell

Stow

GNU stow 是管理符号链接(symlink)的一个小公举。主要用于 symlink 你的 dotfiles 如 emacs,git,fish/zsh 的配置文件。安装只需要
brew install stow
安装了 stow 之后,我们可以开始 symlink 一些 dotfiles 了。完整使用 stow 和 dotfiles 的流程可以参考 https://github.com/jcouyang/dotfiles
当你的 dotfiles 都妥妥的 symlink 到 ~/dotfiles 后,push 到 github 上就再也不怕换电脑了。

Git 常用别名

几乎每个人都会使用一些方法比如 Git 别名来提高效率,几乎所有人都会把使用git st来代替git status。然而这需要手动设置,每个人也都不完全一样。
Oh My Zsh 提供了一套系统别名(alias),来达到相同的功能。比如gst作为git status的别名。而且 Git 插件是 Oh My Zsh 默认启用的,相当于你使用了 Oh My Zsh,你就拥有了一套高效率的别名,而且还是全球通用的。是不是棒棒哒?下面是一些我常用的别名:
Alias Command
gapa git add --patch
gc! git commit -v --amend
gcl git clone --recursive
gclean git reset --hard && git clean -dfx
gcm git checkout master
gcmsg git commit -m
gco git checkout
gd git diff
gdca git diff --cached
glola git log --graph --pretty = format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --all
gp git push
grbc git rebase --continue
gst git status
gup git pull --rebase
gwip git add -A; git rm $(git ls-files --deleted) 2> /dev/null; git commit -m "--wip--"
完整列表请参考:https://github.com/robbyrussell/oh-my-zsh/wiki/Plugin:git

Scroll Reverser

当你在浏览一个很长的网页时,你看完了当前显示的内容,想要看后续的内容,你可以在 Trackpad 上双指上滑,或者鼠标滚轮向上滚动。这是被称作“自然”的滚动方向。
然而在 Windows 里鼠标滚动的行为是相反的:鼠标滚轮向下滚动才会让浏览器显示后续的内容,向上滚动会达到页面的顶部。你可以在 OS X 的系统偏好设置里修改(选择System Preferences > Trackpad,在Scroll & Zoom标签页中不选中Scroll direction: natural),但是这样会同时改变鼠标滚轮的方向和 Trackpad 的方向。
要想只改变鼠标滚轮的方向,而保持 Trackpad 依旧是“自然”的,我们需要 Scroll Reverser:
brew cask install scroll-reverser
PS:这货会让三指点击失效

ShiftIt

原生 OS X 下只能手动调整窗口大小,所以我们需要窗口管理工具。我用过很多窗口管理工具,可惜大部分工具都存在快捷键冲突的问题(对我来说主要是 IntelliJ IDEA)。ShiftIt 是少见的没有冲突的窗口管理工具:
brew cask install shiftit
PS:ShiftIt的旧版本需要安装 X11,最新版本已经修正了这个问题。
替代者有 SizeUp,主要快捷键和 ShiftIt 相同。
当然如果喜欢 hacking,Slate 是个不错的 hackable 的窗口管理工具。配置可以参照 http://thume.ca/howto/2012/11/19/using-slate/

Sublime Text 2

安装:
brew cask install sublime-text
在命令行中指定使用 Sublime Text 打开某文件,是一个非常常用的功能,一般我们会按照 OS X Command Line 中所说执行 ln -s "/Applications/Sublime Text 2.app/Contents/SharedSupport/bin/subl" ~/bin/subl 来增加subl链接。但是如果你用 brew-cask 安装的话,恭喜你,你不需要运行这个命令,因为 brew-cask 自动帮你做了这件事情。而且你卸载 Sublime Text 的时候 brew-cask 会自动删掉这个链接。
同时 Oh My Zsh 也提供了 Sublime Text 插件,叫做sublime。参考:https://github.com/robbyrussell/oh-my-zsh/tree/master/plugins/sublime,这个插件和通过 brew-cask 安装的 Sublime Text 完美兼容。
替代品有 Atom、TextMate、Sublime Text 3 等,跟 Sublime Text 2 一样,用 brew-cask 安装的话命令行工具会被自动加入$PATH

MacDown

MacDown 是 Markdown 编辑器。由于 Mou 一直不支持代码高亮,我就转向了 MacDown。完美支持 GFM
我特别喜欢 Markdown,我用 Makdown 来写文章(包括本文),写幻灯片(reveal.js)。Markdown 可以让我专注于内容本身,而无需花精力在排版和样式上。
安装:
brew cask install macdown

z

在打开终端后,你是怎么进入项目的工作目录?是cd xxx⌃R还是用别名?
z 工具可以帮你快速进入目录。比如在我的 Mac 上运行z cask就会进入/usr/local/Library/Taps/caskroom/homebrew-cask/Casks目录。
这货的安装非常方便,甚至都不需要下载任何东西,因为它已经整合在了 Oh My Zsh 中。编辑~/.zshrc文件,在plugins=(git)这行中加上z变成plugins=(git z),然后运行source ~/.zshrc重新加载配置文件,就可以使用 z 了。
替代品有 autojump。autojump 需要使用 brew 安装。

Vimium

Vimium 是一个 Google Chrome 扩展,让你可以纯键盘操作 Chrome,把你的 Chrome 变成“黑客的浏览器”。
安装方法请参考官方网站。
其他浏览器也有类似的工具,比如 FireFox 的 KeySnail

LastPass

LastPass 是管理密码的工具,支持二次验证,提供所有浏览器插件以及 Mac 桌面版本。
最重要的是,它提供 命令行 的版本,可以直接通过 brew 安装
brew install lastpass-cli --with-pinentry
之后,只需要登陆:
lpass login you@email.com
就可以拷贝密码或者集成到其他命令中了:
lpass show --password gmail.com -c

SourceTree

SourceTree 是 Atlassian 公司出品的一款优秀的 Git 图形化客户端。如果你发现命令行无法满足你的要求,可以试试 SourceTree。
安装:
brew cask install sourcetree
用 brew-cask 安装会自动增加命令行工具stree$PATH里。在命令行中输入stree可以快速用 SourceTree 打开当前 Git 仓库。详细用法请参见stree --help

CheatSheet

CheatSheet 能够显示当前程序的快捷键列表,默认的快捷键是长按
CheatSheet
安装:
brew cask install cheatsheet

Alfred

Mac 用户不用鼠标键盘的必备神器,配合大量 Workflows,习惯之后可以大大减少操作时间。
上手简单,调教成本在后期自定义 Workflows,不过有大量雷锋使用者提供的现成扩展,访问这里挑选喜欢的,并可以极其简单地根据自己的需要修改。
安装:
brew cask install alfred

3. 开发工具

Java

现在 OS X 都不会自带 JDK 了,所以进行 Java 开发的话,需要下载 JDK。在 brew-cask 之前,我们需要从 https://developer.apple.com/downloads/ 或者 Oracle 网站上下载。还有更麻烦的--卸载 JDK 和升级 JDK。
JDK 安装文件是 pkg 格式,卸载和.app不一样,且没有自动卸载方式。
而 brew-cask 提供了自动安装和卸载功能,能够自动从官网上下载并安装 JDK 8。
brew cask install java
如果你需要安装 JDK 7 或者 JDK 6,可以使用homebrew-cask-versions
brew tap caskroom/versions
brew cask install java6
在 OS X 上,你可以同时安装多个版本的 JDK。你可以通过命令/usr/libexec/java_home -V来查看安装了哪几个 JDK。
那问题来了,当你运行java或者 Java 程序时使用的是哪个 JDK 呢?在 OS X 下,java也就是/usr/bin/java在默认情况下指向的是已经安装的最新版本。但是你可以设置环境变量JAVA_HOME来更改其指向:
$ java -version
java version "1.8.0_60"
Java(TM) SE Runtime Environment (build 1.8.0_60-b27)
Java HotSpot(TM) 64-Bit Server VM (build 25.60-b23, mixed mode)
$ JAVA_HOME=/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home java -version
java version "1.6.0_65"
Java(TM) SE Runtime Environment (build 1.6.0_65-b14-466.1-11M4716)
Java HotSpot(TM) 64-Bit Server VM (build 20.65-b04-466.1, mixed mode)
其中JAVA_HOME=/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home可以用JAVA_HOME=`/usr/libexec/java_home -v 1.6`这种更加通用的方式代替。

jEnv

也可以使用 jEnv 来管理不同版本的 JDK,这个工具跟 rbenv 类似,通过当前目录下的.java-version来决定使用哪个 JDK。jEnv 也可以用 brew 安装。不过要使用 jEnv 要有几个问题:
  • 需要手动把eval "$(jenv init -)"加入 profile,没有 Oh My Zsh 插件。这点是我非常反感的。
    可以把eval "$(jenv init -)"加入~/.zlogin,这样可以避免修改~/.zshrc
  • 需要手动添加 JDK,不会自动采集系统 JDK。跟 Ruby 不同,OS X 已经提供/usr/libexec/java_home工具来管理安装的 JDK。
  • 需要 jenv rehash。这个是跟 rbenv 学的。
所以我建议不要使用 jEnv。

民间使用的 Java 版本切换方法

添加以下脚本到当前 shell 配置文件中:~/.zprofile或者~/.bash_profile
function setjdk() {
    export JAVA_HOME=`/usr/libexec/java_home -v $@`
}
这样我们就可以通过输入一条命令进行版本切换了:
setjdk 1.8

Java[OCD]

作为一个强迫症患者,每当我看到 Java 的错误写法就想纠正过来。
当指编程语言时,Java 的正确写法是首字母大写,其余小写。其他写法比如JAVAjava都是不对的。
在其他一些地方会使用小写的java
  • java命令
  • 原文件Main.java
  • 包名java.lang
只有在全大写的标题里使用JAVA或者环境变量JAVA_HOME

IntelliJ IDEA

Java 开发必备工具 IntelliJ IDEA。可以安装 Ultimate Edition:
brew cask install intellij-idea
也可以安装开源免费的 Community Edition:
brew cask install intellij-idea-ce
IntelliJ IDEA 有几套内建的快捷键方案(Keymap)。其中适用于 OS X 的有Mac OS XMac OS X 10.5+两种。区别是:
  • Mac OS X方案和其他平台上的快捷键类似,
  • Mac OS X 10.5+更加符合 OS X 常用的快捷键。
一个团队使用不同的快捷键会严重影响效率。可以用View | Quick Switch Scheme⌃ Back Quote)快速切换 Keymap。
如果可以选择的话,我建议使用Mac OS X方案。因为我经常遇到使用 Windows 的客户,而 Windows 平台上的快捷键和Mac OS X方案类似。
可以从 IDEA 的Help > Default Keymap Reference打开快捷键的参考手册。不过从这里打开的是Mac OS X 10.5+方案的,而Mac OS X方案的可以从这里找到:http://www.basrikahveci.com/static/ij_keymap_mac.pdf

rbenv

人人都需要一个 Ruby 版本管理工具。rbenv 就是这样一个轻量级工具,它可以通过 brew 安装。
安装:
brew install rbenv ruby-build
然后在~/.zshrc中加上rbenv插件。否则你需要手动添加eval "$(rbenv init -)"~/zshrc或者~/.zprofile文件里。
有时候项目会依赖一些奇怪的版本号,比如ruby-2.1.0,这个时候你需要 rbenv-aliases 帮忙:
brew install rbenv-aliases
替代品有 RVM、chruby。因为 RVM 不能通过 brew 安装,并且安装的时候会没有节操的修改一堆文件,所以被我早早的弃用了。chruby 也是一个轻量级工具,而且可以完美的和 Oh My Zsh 集成在一起,我看到有些生产环境在用它。

Ruby 常用别名

几乎所有 Ruby 开发人员都会把bi作为bundle install的别名。Oh My Zsh 提供builder插件,这个插件提供了一套别名,比如bibe。同时还能让你在运行一些常用 gem 的时候直接输入rspec,不需要be rspec这样了。具体包括哪些命令请参考这里
Z shell 对于[]符号有特殊的处理,所以在运行rake task[parameter]的时候会报错,你需要改成rake task\[parameter\]或者noglob rake task[parameter]。然而 Oh My Zsh 已经看穿这一切,自带的 rake 插件已经解决了这个问题:brake task[parameter]
添加插件的时候注意把rake放到bundler后面,例如这样:
plugins=(git z sublime history rbenv bundler rake)

参考资料

from https://github.com/macdao/ocds-guide-to-setting-up-mac/blob/master/README.md