octopress安装和定制


ruby安装

参考:http://octopress.org/docs/setup/
一个是rvm,rbenv
rvm是出现最早功能最强大,但是有点复杂。
rbenv是37sigle功能推出的,比较受欢迎。


rvm安装:
curl -L https://get.rvm.io | bash -s stable --ruby


echo '[[ -s "$HOME/.rvm/scripts/rvm" ]] && . "$HOME/.rvm/scripts/rvm" # Load RVM function' >> ~/.bash_profile
source ~/.bash_profile

# If using Zsh do this instead
echo '[[ -s $HOME/.rvm/scripts/rvm ]] && source $HOME/.rvm/scripts/rvm' >> ~/.zshrc
source ~/.zshrc
rbenv安装:


cd
git clone git://github.com/sstephenson/rbenv.git .rbenv
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
git clone git://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
source ~/.bash_profile

touble shot:

在zsh中,启动rbenv init -会提示错误

$HOME/.rbenv/libexec/../completions/rbenv.bash:14: command not found: complete
修改为:


eval "$(rbenv init - zsh)"

安装ruby rehash


rbenv install 1.9.3-p0
rbenv global 1.9.3-p0
rbenv rehash
关于为什么要做rehash,解释如下:
新装的gem(以前重没装过)一定要rehash在.rbenv/shims下生成可执行程序,像zsh要自动补全还需要 hash -r .不过因为 rbenv init - 里会调用rbenv rehash,所有新开个窗口是不需要的.我的用法是bundler管理gemset,在~/.bundle/config里设置BUNDLE_PATH为vendor/bundle , 配合shell的一个小函数为常用命令添加alias,在发现Gemset的时候自动加上bundle exec ( rbenv.zsh ).通过bundler安装bundle exec执行是不需要rehash的。


openssl

启动时提示:
require’: cannot load such file – openssl (LoadError)
解决办法:
apt-get install libssl-dev
重新安装ruby
rbenv install 1.9.3-p0


安装octopress


git clone git://github.com/imathis/octopress.git octopress
cd octopress    # If you use RVM, You'll be asked if you trust the .rvmrc file (say yes).
ruby --version  # Should report Ruby 1.9.3
遇到的问题,安装后我clone了octopress然后执行gem但缺少zlib库。
解决办法:


sudo apt-get install zlib1g-dev
rvm reinstall 1.9.3 #重新安装ruby
安装依赖:


gem install bundler
rbenv rehash    # If you use rbenv, rehash to be able to run the bundle command
bundle install

Deploying to Github Pages

参考:http://octopress.org/docs/deploying/github/


rake setup_github_pages
他会做几件事:

  1. 询问你的github url
  2. 把当前origin rename为imathis/octopress
  3. 把你的github pages作为default origin remote
  4. 从当前master分支转为source分支
  5. 把master分支设置为_deploy目录,用于发布页面


然后运行


rake generate
rake deploy
这会生成website在_deploy目录,然后提交到github。


然后提交source分支


git add .
git commit -m 'your message'
git push origin source

gh-pages

还可以通过project pages页面来部署,这样你的页面的访问地址为:
http://username.github.com/project
适用于多个工程的情况,每个工程一个站点。
实际上显示时,github会搜索你工程下的gh-pages分支,作为显示。


重新安装octopress



git clone -b source git@github.com:username/username.github.com.git octopress #下载source版本(用于编辑)
cd octopress
git clone git@github.com:username/username.github.com.git _deploy #下载_deploy版本(用于发布)
bundle install
我是升级的octopress,所以我还是需要重复之前的安装过程,需要安装ruby,gem,bunlder等。
然后执行
rake setup_github_pages


rake install[theme]
安装一个主题,把github上的source中_post目录cp过来,以及修改的插件等手工合并进来,然后使用git push -f 强行push的。


安装主题

下载后放到.themes目录下,然后执行对应主题的安装,如:
rake install[‘bootstrap’]
rake generate


rake install\[‘blanket’\]
有一点不好的是,code区显示不完全。还是有点缺憾。


我目前使用的是:
bootstrap-theme虽然使用了bootstrap,基石很强大,但调整的不好。
文章和文章之间没有隔离,不方便区分。
还有就是字体使用的是固定px,13px行间距是18px,为什么不用em呢?
我尝试修改sass中的basefont为1em,但整体显示就乱了,有的code无法显示,所以干脆先这么用这吧。


主题下载页
https://github.com/bkutil/bootstrap-theme
重新安装octopress


配置

date_format: “%Y年%m月%d日”


个性化定制

邮箱地址图片化

很多博主都将邮箱地址转化成图片,目的是为了防止垃圾邮件,我也赶了一下时髦。


邮箱地址生成图片的网址是:


http://services.nexodyne.com/email/index.php
http://pic.sdodo.com/tool/mailpic/


about分页

在source下新建about目录,并在里面添加index.markdown文件。
编辑导航条source/_includes/custom/navigation.html
注意:index.markdown文件需要加上头,否则会找不到。


在侧边栏中a天际about me
在custom/asides/about.html中添加About Me信息


<section>
  <h1>About Me</h1>
  <p><img src="/images/about.jpg"></p>
  <p>some thing</p>
  <p><a href="mailto:emmoblin@gmail.com"><img src="/images/my_email.png" alt="emmoblin@gmail.com"></a></p>
</section>

添加友情链接

在custom/asides/blog_link.html中添加友情链接


  <h1>大牛博客</h1>
  <ul>
    <li>
      <a href="http://coolshell.cn/">酷壳CoolShell</a>
    </li>
    <li>
      <a href="http://mindhacks.cn/">刘未鹏MIND HACKS</a>
    </li>
    <li>
      <a href="http://blog.codingnow.com/">云风</a>
    </li>
    <li>
      <a href="http://www.cnblogs.com/Solstice/">陈硕</a>
    </li>
  </ul>
</section>

侧边栏添加Disqus评论

在custom/asides/recent_comment.html中添加Disqus评论


<section>
  <h1>近期评论</h1>
<script type="text/javascript" src="http://emmoblin.disqus.com/combination_widget.js?num_items=5&hide_mods=0&color=blue&default_tab=recent&excerpt_length=200"></script><a href="http://disqus.com/">Powered by Disqus</a>
</section>

增加一键分享

我目前使用的是bshare。


在_config.yml中增加bshare: true。 在“source_includes\post”下的sharing.html中增加如下代码.
上述的代码由bshare产生,可以自己选择所需的外观。 这样,在每一篇文章的最下方会出现一个分享的小工具。


参考资料

使用了org-jekyll.el

我是使用org-mode来管理笔记的,使用了org-jekyll插件来把org笔记转化为jekyll的格式。
首先通过C-c C-e 把整个project进行export,生成cache。
之后org-jekyll-export-blog,根据cache的内容生成对应的octopress文件。
org-jekyll是根据~/.org_timestamp/的cache生成的。所以先要export project,之后再用org-jekyll。


org-jekyll-export-current-entry 使用时光标所在entry进行导出。


所有source/_posts目录下的html都可以重新生成,注意有的时候格式不对,比如title中不能包含中文,
会导致rake genernate错误。


LVM介绍


LVM是建立在硬盘和分区之上的一个逻辑层,来提高磁盘分区管理的灵活性。通过LVM系统管理员可以轻松管理磁盘分区,如:将若干个磁盘分区连接为一个整块的卷组(volumegroup),形成一个存储池。管理员可以在卷组上随意创建逻辑卷组(logicalvolumes),并进一步在逻辑卷组上创建文件系统。管理员通过LVM可以方便的调整存储卷组的大小,并且可以对磁盘存储按照组的方式进行命名、管理和分配。
而且当系统添加了新的磁盘,通过LVM管理员就不必将磁盘的文件移动到新的磁盘上以充分利用新的存储空间,而是直接扩展文件系统跨越磁盘即可。


LVM基本术语

物理存储介质(The physical media)
这里指系统的存储设备:硬盘,如:/dev/hda1、/dev/sda等等,是存储系统最低层的存储单元。


物理卷PV(physical volume)
物理卷就是指硬盘分区或从逻辑上与磁盘分区具有同样功能的设备(如RAID),是LVM的基本存储逻辑块,但和基本的物理存储介质(如分区、磁盘等)比较,却包含有与LVM相关的管理参数。


卷组VG(Volume Group)
LVM卷组类似于非LVM系统中的物理硬盘,其由物理卷组成。可以在卷组上创建一个或多个“LVM分区”(逻辑卷),LVM卷组由一个或多个物理卷组成。


逻辑卷LV(logical volume)
LVM的逻辑卷类似于非LVM系统中的硬盘分区,在逻辑卷之上可以建立文件系统(比如/home或者/usr等)。


PE(physical extent)
每一个物理卷被划分为称为PE(Physical Extents)的基本单元,具有唯一编号的PE是可以被LVM寻址的最小单元。PE的大小是可配置的,默认为4MB。


LE(logical extent)
逻辑卷也被划分为被称为LE(Logical Extents) 的可被寻址的基本单位。在同一个卷组中,LE的大小和PE是相同的,并且一一对应。


../img/lvm_vg.jpg


VGDA(卷组描述符区域)
和非 LVM 系统将包含分区信息的元数据保存在位于分区起始位置的分区表中一样,逻辑卷以及卷组相关的元数据被保存在位于物理卷起始处的 VGDA 中。VGDA 包括以下内容:PV 描述符、VG 描述符、LV 描述符、和一些 PE 描述符。系统启动 LVM 时激活 VG,并将 VGDA 加载至内存,来识别 LV 的实际物理存储位置。当系统进行 I/O 操作时,就会根据 VGDA 建立的映射机制来访问实际的物理位置。


创建和管理lvm

分区

使用分区工具(如:fdisk等)创建LVM分区,方法和创建其他一般分区的方式是一样的,区别仅仅是LVM的分区类型为8e。


创建物理卷

创建物理卷的命令为pvcreate,利用该命令将希望添加到卷组的所有分区或者磁盘创建为物理卷。


#pvcreate /dev/hda5

创建卷组

创建卷组的命令为vgcreate,将使用pvcreate建立的物理卷创建为一个完整的卷组:


# vgcreate web_document /dev/hda5 /dev/hdb
vgcreate在创建卷组 web_document 以外,还设置使用大小为4 MB的PE(默认为4MB),这表示卷组上创建的所有逻辑卷都以 4 MB 为增量单位来进行扩充或缩减。由于内核原因,PE大小决定了逻辑卷的最大大小,4 MB 的PE决定了单个逻辑卷最大容量为 256 GB,若希望使用大于256G的逻辑卷则创建卷组时指定更大的PE。PE大小范围为8 KB 到 512 MB,并且必须总是 2 的倍数(使用-s指定)


激活卷组


# vgchange -ay web_document

添加新的物理卷到卷组中

当系统安装了新的磁盘并创建了新的物理卷,而要将其添加到已有卷组时,就需要使用vgextend命令:


# vgextend web_document /dev/hdc1

查看物理卷信息


# pvdisplay /dev/hda1

从卷组中删除一个物理卷

要从一个卷组中删除一个物理卷,首先要确认要删除的物理卷没有被任何逻辑卷正在使用.
如果某个物理卷正在被逻辑卷所使用,就需要将该物理卷的数据备份到其他地方,然后再删除。


# vgreduce web_document /dev/hda1

创建逻辑卷


# lvcreate -L1500 –n www1 web_document
该命令就在卷组web_document上创建名字为www1,大小为1500M的逻辑卷,并且设备入口为/dev/web_document/www1


创建文件系统

推荐使用reiserfs文件系统,来替代ext2和ext3


删除一个逻辑卷

删除逻辑卷以前首先需要将其卸载,然后删除:


# umount /dev/web_document/www1
# lvremove /dev/web_document/www1

扩展逻辑卷大小

LVM提供了方便调整逻辑卷大小的能力,扩大为12G


# lvextend -L12G /dev/web_document/www1
增加1G
# lvextend -L+1G /dev/web_document/www1
增加了逻辑卷的容量以后,就需要修改文件系统大小以实现利用扩充的空间。笔者推荐使用reiserfs文件系统来替代ext2或者ext3。因此这里仅仅讨论reiserfs的情况。Reiserfs文件工具提供了文件系统大小调整工具:resize_reiserfs。对于希望调整被加载的文件系统大小:


# resize_reiserfs -f /dev/web_document/www1
对于使用ext2或ext3文件系统的用户可以考虑使用工具
ext2resize。
http://sourceforge.net/projects/ext2resize


减少逻辑卷大小

使用lvreduce即可实现对逻辑卷的容量,同样需要首先将文件系统卸载:
要先减少文件系统,然后再减少逻辑卷


# umount /data/wwwroot
# resize_reiserfs -s-2G /dev/web_document/www1
# lvreduce -L-2G /dev/web_document/www1
# mount -treiserfs /dev/web_document/www1 /data/wwwroot

灵活

逻辑卷可以再组合成pv,和vg,再次进行lvm。
而且一个卷组可以跨多个磁盘。
如果想自己做实验可以自己创建空洞文件进行lvm练习。


dd if=/dev/zore of=./loop1.img bs=1G count=0 seek=100
这就创建了一个100G的稀疏文件,文件大小是100G,但占用的空间是0.
然后使用losetup进行加载。就可以当/dev/loop0 磁盘使用了。


snapshot

lvm可以创建镜像,创建时选择创建允许多大的空间用于记录变化。
创建镜像后实际上就是和原始lv独立,但如果原始lv删掉了,则所有的snap也就丢失了。
snap和原始lv都可以后续修改,而且snap可以和原始lv进行合并,使原始lv变为snap当前的样子。

lvm常用管理工具:


功能物理卷卷组逻辑卷
扫描pvscanvgscanlvscan
查看pvdisplayvgdisplaylvdisplay
新建pvcreatvgcreatlvcreat
卸载pvremovevgremovelvremove
增大vgextendlvextend
减小vgreducelvreduce


lvs
pvs


先衰竭训练法


先衰竭训练法

先衰竭法是目前增大肌肉围径的有效方法。
其做法是要想发展那块肌肉,先选择只发展这块肌肉的局部肌肉练习来训练,做8-10次直到疲劳,使其衰竭,然后在3-5秒之内跑向另一器械,做一个以发展这块肌肉为主的综合肌肉群练习,用70%的重量做到极限,这样交替训练4组左右,肌肉会感受到极大的刺激。据研究,这样能有效地刺激肌肉生长,促进其发育。


胸大肌的先衰竭训练法

发达胸大肌的局部有效练习:仰卧飞鸟;
发达胸大肌综合肌群的练习:卧推(包括宽握、中握、窄握),它除了发展胸大肌外,还能发展肱三头肌、三角肌前部和前锯肌。


先用只能举8-10次的重量做仰卧飞鸟练习,直到起不来,
紧接着跑到卧推架前用事先准备好的60-70%重量做卧推,尽力举次数,直到起不来算一组,
共做4组左右,累计总运动量为8组约50次左右。


三角肌的先衰竭训练法:

发达三角肌的局部肌肉练习:哑铃前平举 主要发展三角肌前束;哑铃侧平举主要发展三角肌中束;俯身后斜举主要发展三角肌后束。
发达三角肌的综合练习:颈后宽推,这个练习既能发展三角肌,还能发展肱三头肌,对胸大肌、前锯肌也有影响。


为发达三角肌将这两个有效练习有机地结合在一起训练,其效果会更好。
每组动作:是先用只能平举8-10次的重量做哑铃来练习。直到起不来,紧接着跑到放置在另一侧的杠铃前,用做(70%),直到一个起不来算一大组,共做4大组。


肱三头肌的先衰竭训练法

发达肱三头肌的局部肌肉练习:各种臂屈伸,如颈后臂屈伸、弓身臂屈伸等
发达肱三头肌的综合练习:是窄卧推


先做颈后臂屈伸6-10次直到疲劳,然后迅速跑向深蹲架前拿起架上事先放好的杠铃(杠铃重量为自己最高重量的60-70%),
连续举直到起不来,这样两种练习算一大组,共做4大组,肱三头肌就会很胀,刺激很深。


竖脊肌(后腰)的先衰竭训练法

发达后腰竖脊肌的局部肌肉练习:负重山羊挺身
发达后腰竖脊肌的综合练习:弓身、屈腿硬拉等。


../img/shanyangtingshen.gif
先在山羊上做负重挺身6-10次直到挺不起为止,紧接着跑向深蹲架前肩负杠铃做弓身练习(或做硬拉),直到疲劳。将这两个练习组合在一起训练4组,背肌就能得到很好的刺激。


大腿的先衰竭训练法

发达股四头肌的局部肌肉练习:负重腿屈伸
发达腿部肌肉的综合肌群练习:深蹲,
../img/qutui.gif


尽力做8次左右负重腿屈伸,紧接着做也尽力做6-8次深蹲,这样交叉轮换做8组(4大组)约50次,股四头肌就会因刺激较深而发胀。


背阔肌的先衰竭训练法

发达背阔肌的局部肌肉练习:宽握颈后引体向上
发达背阔肌的综合练习:坐姿划船


先宽握颈后引体向上10-15次直到拉不起为止,紧接着跑向做坐姿划船练习,直到疲劳。将这两个练习组合在一起训练4组,背阔肌就能得到很好的刺激。


总结

先衰竭原理之所以先进,从理论上讲它符合极限负荷后的超量恢复的原则。
这是因为肌体精疲力竭地负荷之后,首先功能能力大大减退,紧接着在恢复防疲肌体由适应一提高,超过它原有的水平。


linux下3g网卡拨号

需要安装的软件usb_modeswitch,wvdial
usb_modeswitch用于将usb3g转换为usb modem模式,这样才能拨号。最好到官网下载最新代码,包含的3g网卡类型会更全。最主要的就是usb_modeswitch_data。
http://www.draisberghof.de/usb\_modeswitch/#download


安装usb_modeswitch_data

进入目录,执行
sudo make install
会安装对应的udev文件到/lib/udev/rules.d目录。


不过我发现自动转换没有效果,暂时先不查了。
直接使用命令行转:
usb_modeswitch -c /etc/usb_modeswitch.conf
如果转换成功会出现/dev/ttyUSB0-3,dmesg也会有输出信息。


usb_modeswitch.conf


######################################################## 
# ZTE A371B
#
# Contributor: Wang Lei

DefaultVendor= 0x19d2
DefaultProduct=0x0169

TargetVendor=  0x19d2
TargetProduct= 0x0170

MessageContent="5553424312345678000000000000061b000000020000000000000000000000"
NeedResponse=1

wvdial

这个难了,wvdial负责发送AT命令给usb modem,进行拨号。但不同的3g卡发送的指令也不一样。
我是在xp上安装了usb抓包软件,把xp上官方的3g拨号过程进行了抓包分析,提取出如下序列:



[Dialer Defaults]
Init1 = AT
Init2 = AT+CIMI
Init3 = AT+CMEE=1
Init4 = ATE0
Init5 = AT+CFUN=1
Init6 = AT+CLCK="SC",2
Init7 = AT+cgdcont=1,"ip","CMNET"
Modem Type = USB Modem
Baud = 460800
New PPPD = yes
Modem = /dev/ttyUSB0
ISDN = 0
Phone = *98*1#
Password = any
Username = any
Stupid Mode = 1

遇到的问题

我的x230上无线鼠标的usb接收器貌似总是捣乱,拔了接收器,换了个usb口插3g,就可以ok了。



linux下3g网卡拨号

需要安装的软件usb_modeswitch,wvdial
usb_modeswitch用于将usb3g转换为usb modem模式,这样才能拨号。最好到官网下载最新代码,包含的3g网卡类型会更全。最主要的就是usb_modeswitch_data。
http://www.draisberghof.de/usb\_modeswitch/#download


安装usb_modeswitch_data

进入目录,执行
sudo make install
会安装对应的udev文件到/lib/udev/rules.d目录。


不过我发现自动转换没有效果,暂时先不查了。
直接使用命令行转:
usb_modeswitch -c /etc/usb_modeswitch.conf
如果转换成功会出现/dev/ttyUSB0-3,dmesg也会有输出信息。


usb_modeswitch.conf


######################################################## 
# ZTE A371B
#
# Contributor: Wang Lei

DefaultVendor= 0x19d2
DefaultProduct=0x0169

TargetVendor=  0x19d2
TargetProduct= 0x0170

MessageContent="5553424312345678000000000000061b000000020000000000000000000000"
NeedResponse=1

wvdial

这个难了,wvdial负责发送AT命令给usb modem,进行拨号。但不同的3g卡发送的指令也不一样。
我是在xp上安装了usb抓包软件,把xp上官方的3g拨号过程进行了抓包分析,提取出如下序列:



[Dialer Defaults]
Init1 = AT
Init2 = AT+CIMI
Init3 = AT+CMEE=1
Init4 = ATE0
Init5 = AT+CFUN=1
Init6 = AT+CLCK="SC",2
Init7 = AT+cgdcont=1,"ip","CMNET"
Modem Type = USB Modem
Baud = 460800
New PPPD = yes
Modem = /dev/ttyUSB0
ISDN = 0
Phone = *98*1#
Password = any
Username = any
Stupid Mode = 1

遇到的问题

我的x230上无线鼠标的usb接收器貌似总是捣乱,拔了接收器,换了个usb口插3g,就可以ok了。



fstab恢复

不小心配置fstab结果参数写错了,导致重启后无法挂载,系统进不去。
从grub进入recover模式,选择进入root。
但此时根文件系统挂载的是只读的,所以无法修改fstab。
重新挂载为rw就ok了,非常关键。
mount -n -o remount,rw /
之后就可以修改了fstab了。

git服务器开源软件


在服务器上部署git

git clone –bare my_project my_project.git
其实 clone 操作基本上相当于 git init 加 git fetch。


通过git账户访问

第二个办法是在主机上建立一个 git 账户,让每个需要写权限的人发送一个 SSH 公钥,然后将其加入 git 账户的~/.ssh/authorized_keys 文件。这样一来,所有人都将通过 git 账户访问主机。这丝毫不会影响提交的数据 — 访问主机用的身份不会影响提交对象的提交者信息。


$ sudo adduser git
$ su git
$ cd
$ mkdir .ssh


只要把它们逐个追加到 authorized_keys 文件尾部即可:


$ cat tmp/id_rsa.john.pub >> ~.ssh/authorized_keys
$ cat tmp/id_rsa.josie.pub >> ~.ssh/authorized_keys
$ cat tmp/id_rsa.jessica.pub >> ~.ssh/authorized_keys
现在可以用 –bare 选项运行 git init 来建立一个裸仓库,这会初始化一个不包含工作目录的仓库。


$ cd /opt/git
$ mkdir project.git
$ cd project.git
$ git –bare init
这时,Join,Josie 或者 Jessica 就可以把它加为远程仓库,推送一个分支,从而把第一个版本的项目文件上传到仓库里了。值得注意的是,每次添加一个新项目都需要通过 shell 登入主机并创建一个裸仓库目录。
$ cd myproject
$ git init
$ git add .
$ git commit -m ‘initial commit’
$ git remote add origin git@gitserver:/opt/git/project.git
$ git push origin master
作为一个额外的防范措施,你可以用 Git 自带的 git-shell 工具限制 git 用户的活动范围。只要把它设为git 用户登入的 shell,那么该用户就无法使用普通的 bash 或者 csh 什么的 shell 程序。编辑 /etc/passwd 文件:


在其他人机子上可以直接clone
git clone git@gitserver:/opt/git/project.git


$ sudo vim /etc/passwd
在文件末尾,你应该能找到类似这样的行:


git:x:1000:1000::/home/git:/bin/sh
把 bin/sh 改为 /usr/bin/git-shell (或者用 which git-shell 查看它的实际安装路径)。该行修改后的样子如下:


git:x:1000:1000::/home/git:/usr/bin/git-shell




gitweb

git自带的cgi脚本
git instaweb –httpd=lighttpd


repo

git仓库太大会导致git操作很慢,那么分成多个子项目,用repo来管理。



代码抽取

git cherry-pick <commit>


分支合并

git merge
git rebase <upstream> [<branch>]
rebase 可以让你看起来是基于最新的代码实现的改动。


git submodule

子模块允许你将一个git仓库当作另一个git仓库的子目录。


gitk

安装apt-get install gitk


git log –graph

可以添加到git的配置文件中


git help workflows

查看推荐的工作流



GITolite

Gitolite 是一款 Perl 语言开发的 Git 服务管理工具,通过公钥对用户进行认证,并能够通过配置文件对写操作进行基于分支和路径的的精细授权。GITolite 采用的是SSH协议,并需要使用公钥 验证。也就是说 GITolite会根据管理员预先定义好的设置,根据客户的SSH,对于来自不同客户端的请求进行权限控制,只读,或者读写,甚至于精确到某个文件夹,某个文件的权限。


gerrit

前面我们说到了对Gitolite是对于开发人员的一种授权,但一旦保证了授权,就能够保证版本库的稳定吗?如果获得授权的人乱搞代码,或者改错代码,那版本库照样会出现不稳定的情况的。就像前面在敏捷系列里面说到的一样,在代码改动之后,要引入code review (代码审阅,说code review 比较顺口,还是用code review吧)。在Clearcase条件下,code review是需要把别人的代码整进去版本库之后,再由code reviewer拿下来看的。于是在Google Android项目的开发过程当中,Google为GIT带来了又一个伟大的工具-Gerrit,也有人叫Gerrit2,因为现在用的Gerrit跟Google刚开始整的时候有很大的不同,我们暂且叫它Gerrit就可以。
Gerrit有两个很牛的功能,第一是权限管理,它提供了一个跟GITolite一样的功能,管理用户的读写权限。但它比GITolite好用,对权限的控制都在它提供的网页系统里面完成,不用push啥的!第二是Gerrit为GIT带来强制性的code review,除非你某某是管理员。任何的代码改动都需要有人approve之后,这个代码改动才有可能进入公共代码库,如果没有经过approve或者被人reject了,即使你已经push了五百年,这代码依旧进不了公共版本库。而且 相比起裸奔时代的code review,Gerrit提供一个在线review 的系统,所有的操作都在它提供的系统上面点点点就能搞定的。
首先我们来看看权限控制,Gerrit有10种不同的权限,其中有读写权限,code review的权限等等。每个权限的设置包括两部分:权限本身,以及权限授予的组。




Jenkins

如果用了Gerrit,那么每一个代码改动都要经过code review approve 并且要验证。code review还好说,可验证就麻烦了。如果每个改动都要人手拿到本地,至少去确保能编译通过吧,那谁都会疯了的!!!话说IT人的精品特质之一就是懒,所以有繁琐的地方
往往都会产生自动化 (这貌似也是工业能够向前发展,甚至于社会能够向前发展的一个因素哦,要发扬发扬)。Jenkins就应运而生了。
Jenkins, 曾用名Hudson,是基于Java开发的持续集成的工具。它能够自动监控到公共代码库的版本变更,并且执行我们预先定义好的动作。在动作完成之后,把动作执行的结果回传给有关部门!比如我们可以让Jenkins监听Gerrit上面的代码变更情况,看有没有人提出code review的请求。如果监听到请求,那么Jenkins就偷偷向Gerrit要那个人改了的代码,试着做一些编译以及单元测试。如果这人很牛叉,测试通过。那么Jenkins会告诉Gerrit :“喂,这条友很牛哦,我向毛主席保证,TA的代码改动没有问题”,这时Gerrit就跑过去将这个review item的 verify设置为+1,如果不通过,那就铁面无私地给一个 verify-1.



git权限控制理解

从技术上讲,git可能永远也做不到类似svn的路径授权(读权限)
如果允许按照路径授权,则各个克隆的关系不再是平等的,有的内容多有的内容少,分布式的理念被破坏。
git的授权模型只能实现非零即一的方式,要不拥有全部写权限,要不没有写权限。
要么拥有全部库的读权限,o要么禁用。


看来git的保密性确实不好,要不一视同仁,大家都有全部代码,要不把代码分成多个库。
这样看来在公司内部使用git确实不太方便了。公司最基本的要求就是代码的保护。


Git对于写操作可以精细到目录和分支级别(使用Gitolite作为服务器), 但作为分布式版本库控制系统,在设计上只能实现版本库量子化的读授权。 即某用户对整个版本库要么都能读,要么对整个版本库都不能读。


那么如何控制Git版本库的读授权呢?实际上Git可以通过子模组来实现细粒度的读授权。 即在项目需要精细授权的场合,将版本库拆分为多个Git版本库进行单独授权, 再使用子模组将多个版本库整合为一个。这个操作并不复杂,而且有助于实现项目的模块化。

shell代码片段收集


获取磁盘大小


# Return the size of the drive in MB
get_drive_size () {
  ldrive=$1

  # Make sure you can print disk info using parted
  parted --script /dev/$ldrive print >/dev/null 2>&1

  # If unable to read disk, it's likely it needs a disklabel
  if [  "$?" != "0" ]; then
    echo "Creating a new disklabel on $ldrive" >> $INSTALL_LOG
    echo "parted /dev/$ldrive mklabel msdos" >> $INSTALL_LOG
    output=$(parted -s /dev/$ldrive mklabel msdos)

    # Get the drive size from parted
    lsize=$(parted -s /dev/$ldrive p | grep "^Disk" | awk '{ print $3 }')

    if [ $(echo $lsize | grep error) ]; then
      echo "Unable to read disk label.  Exiting."
      exit 1
    fi
  fi

  # Get the drive size from parted
  lsize=$(parted -s /dev/$ldrive p | grep "^Disk" | awk '{ print $3 }')
  # Get the reported units (mB, GB, kB)
  lmodifier=$(echo $lsize | sed 's/[0-9\.]//g')
  # remove the modifier
  lsize=$(echo $lsize | sed 's/[a-z,A-Z]//g')
  # Remove any fractions
  lsize=$(echo $lsize | cut -f1 -d'.')
  # Translate our size into mB if not there already
  if [ $lmodifier = "GB" ]; then 
    lsize=$(($lsize * 1000))
  elif [ $lmodifier = "kB" ]; then 
    lsize=$(($lsize / 1000))
  fi

  echo $lsize
}

disk_size=`fdisk -l $CF | grep MB | cut -d”:” -f2 | cut -d “,” -f1| sed s/MB//g `


变为大写


upper_str()
{
        upper=`echo $1 | tr "[a-z]" "[A-Z]"`
        echo $upper
}

判断返回值


echo $TOS_VERSION | grep "^3.3.016" 
if [  $? != 0  ]
then 
        VERSION_016="false"
else
        VERSION_016="true"
fi

提问


auto_echo "Are you sure to begin[y/n]:"
while read answer
do
answer=`upper_str $answer`
if [ "$answer" = "Y" ] 
then
break
elif [ "$answer" = "N" ] 
then
write_free
exit
fi
auto_echo "Are you sure to begin[y/n]:"
done

for循环


for x in /var/log/*
do
    echo `basename $x` is a file living in /var/log
done


while and until


myvar=0
while [ $myvar -ne 10 ]
do
    echo $myvar
    myvar=$(( $myvar + 1 ))
done


myvar=0
until [ $myvar -eq 10 ]
do
    echo $myvar
    myvar=$(( $myvar + 1 ))
done

case

*$x为文件名,只获取文件的后缀,至于是为什么现在不明白? *


case "${x##*.}" in
     gz)
           gzunpack ${SROOT}/${x}
           ;;
     bz2)
           bz2unpack ${SROOT}/${x}
           ;;
     *)
           echo "Archive format not recognized."
           exit
           ;;
esac

读取文件


#! /bin/bash  
while read LINE
do
        echo $LINE 
done < /etc/passwd

awk按域搜索的例子


while read line; 
        do cp aaaa $line;
done << (awk '{for(i=1; i <= NF; ++i){if($i ~/^-l/){gsub("^-l","lib",$i); printf("%s.so\n", $i)}}}' libso.txt  | sort -u)