2009年6月9日星期二
2009年6月7日星期日
白领陨落,黑领崛起
这两年总有人在说什么“崛起”。到底是谁在崛起?是黑领。
我在《邓玉娇杀官激起暴虐为什么?》一文中说过:“当权力集团争先恐后地占有社会资源的时候,说明他们已经彻底抛弃面具,权力已经彻底失控。权力集团的成员都知道,这样的疯狂对于统治者与被统治者双方都是不利的,但是,抢得慢的人只能是抢夺战中的落后者,并不能改变抢夺的大趋势,于是,大家都去抢,我死后哪管洪水滔天,巨额存款转到国外,子子孙孙花不完。
“所有的人都看到了这种局面,但是,所有的人都没有办法。于是,那些买不起房、看不起病、上不起学的人,只好借邓玉娇来发泄自己的愤懑。”
中国的黑领是世界上最无耻的群体
才仅仅10年之前,白领还是一个全社会人人称羡的身份。万科地产甚至将其出版的系列图书命名为《白领》。白领是指那种在高级写字楼里上班的专业技术人员,特点是高学历、高收入。特别是写字楼里外资企业,更是白领群体云集的根据地。
白领意味着体面的工作、优雅的修养、丰富的精神体验。从某种意义上讲,白领简直成为时尚的代名词。
白领必定毕业于名牌大学,甚至是硕士、博士或海归,每天朝九晚五打卡,坐在格子间的电脑旁,MSN,麦当劳,卡布奇诺,丁克,地铁,打的,坐经济舱,住星级宾馆,泡吧,煲电话,听蓝调,加班,圣诞节,斯诺克,暂住证,红酒,抽555,住租来或按揭的公寓,买简约的宜家家具,收藏CD,谈论《老友记》,向往 xz,留恋于丽江,铁杆驴友,不看中文报纸不看中国电影,看《国家地理》《名牌》《读书》杂志,看卡夫卡看张爱玲看伊朗电影,洁癖,乡愁,健身,瑜伽,养吉娃娃,香水衣服鞋子泡吧旅游鲜花买书买CD看电影,月光一族。
白领的产生是中国市场经济发展初级阶段末期的典型现象,证明了“知识改变命运 ”。白领大多只出现在一线城市。面对WTO的前夜,这些有文化有知识的年轻人开始尝试一种西方发达国家中产阶级的雅皮士生活。绅士与淑女,是充满这些新思想的青年人的人生目标。《了不起的盖茨比》和《傲慢与偏见》是他们的必读书。爱情、教养、文化、艺术、体验、精神贵族深深地吸引着他们。
10 年
过去,物是人非。回头看看,当年怀着白领梦“范进中举”,当许多大学生兴冲冲踏出大学这个高级职业培训监狱大门的时候,却必须接受与黧黑的农民父亲同场竞
聘的残酷现实。曾经的白领已经老去,在一场百年不遇的经济危机面前,破产的破产,失业的失业,离婚的离婚。当孕育白领的贸易、广告、房地产、IT和制造业风吹雨打流水落花,脆弱的白领蓦然发现,曾经雪白挺括的领口,已经被冰冷的汗水洇得皱皱巴巴一片姜黄。春天来的时候,老去的白领继续徘徊于物价和房价飞涨的城市。伫立在林立的写字楼脚下,他今天会收到一个面试通知么……白领的传说就这样陨落了。
与此同时,一个充满神秘色彩的社会群体已经夺
去了全中国所有的光芒,他们开着“自己的”大排量名牌汽车,出入高档酒楼,高级夜总会,乘坐头等舱或软卧,住星级宾馆,拥有黄金位置的几处豪宅,购全套红
木家具,在位置最好、景观最佳,装修最豪华、质量最安全的办公楼上班,独立办公室,不打卡,饭局,会面,喝茅台五粮液,品天价普洱,抽极品中华,精装《毛
评二十四史》,VIP,炒股投资保险理财,收藏古玩字画珠宝黄金,高级会所,劳力士,路易威登,奢侈品,国际顶级品牌服饰,高尔夫,公派出国,移民,护照,拉斯维加斯,美容减肥按摩,组织体检,疗养,免费医疗,贵族学校,MBO,脱产学习,党校,佣人,情人,养藏獒,带薪假……
他们就是在全中国一线二线三线城市遍地开花,全面崛起的新兴黑领阶层。相对于干干净净清清白白的白领,他们的衣服是黑色的,汽车是黑色的,脸色是黑色的。他们的收入是隐蔽的,生活是隐蔽的,工作是隐蔽的……所谓隐蔽,就是像站在黑夜里的黑衣人,你知道他在,他也知道他在,但你不知道他什么样,在做什么。他们就是就职于政府和官有垄断企业的那个庞大群体。
10年间,官有建筑已经屡屡刷新了所有中国城市的高度。在气度辉煌富丽堂皇的官方办公楼面前,商业写字楼登时被压出逼仄吝啬的寒酸来。从容积率、配套、装修等各方面,拔地而起的“大裤衩”成为城市黑领新贵们的“鸟巢”。白领和他的OFFICE一起,被黑领的裤衩遮住了所有的阳光。
10年间,通过高税收、高房价和垄断政治权力,
官方组织一步步通过各种手段将社会财富向自己手中集中。不仅以重税和重复收费罚款的方式,从横向上苛刻聚敛社会财富,而且以资源浪费和环境污染等方式,从
纵向上大肆透支谋夺子孙后代赖以生存的根基。官有经济在垄断的无竞争市场所向披靡,源源不断的暴利如滚滚长江。水气电油电信金融烟草卫生教育海关公路等行
业自不用说,即使出版、邮政、新华书店、市政、环卫、公交、盐业、矿业、铁路、民航、文化、体育、新闻、旅游、土地等这些领域,因为禁止自由竞争,其利润
之丰厚仍足以使任何外企眼红得流鼻血。在当下中国随便哪一个城市,一个大腹便便的税务监管员都可以开着路虎SUV上班,他的办公室面积有多大、装修得有多豪华不必说,只消告诉你一句,他可以在单位里健身桑拿游泳……
一个刚刚工作两年的警察就已经买车买房——没要父母的钱也没按揭……一个国家电网公司的抄表员基本月薪达到8000元……简单推算一下,全国有1000多个省级,20000个厅级,好几万到十来万个县级,这还不包括北京的中央部门和军队警察系统。较发达地区普通黑领年收入10到20万元极普遍,年终发个十万元奖金不是什么稀奇事,而这也不仅仅是税务部门才有这个财力。
这是“合法”的收入,这一部分财产是不怕公示
的。去年就有新闻称,南方某地所有的黑领都有两部车,而且很正常。人类都知道,对黑领来说,收入绝对不止薪水这一块,医疗交通吃喝拉撒贪污受贿等等,所有
的地方都享受纳税人无偿供养,每月的车贴甚至比农民工辛苦一个月的薪水还要多,他们也可以在超市买个床单裤衩都开发票报销,或者把免费领来的大量昂贵药品
卖钱。甚至嫖娼也要发票。可以说,所谓黑领,就是除了没给其配备法律意义上的配偶外,其它都是享受无偿供给的。
黑领阶层之所以生活水平急剧提高,是因为其垄断了包括政治、法律、经济、信息在内的一切社会资源,他们消耗了至少一半以上的中国国民收入。他们的崛起,构成了中国新二元社会的显赫一极。这个群体虽然相对数量少,但是绝对数量庞大。粗略估计一下,这种以寄生垄断为业的黑领在全国约有 2000万以上。
比起10年前苍白的小资白领来,只有这些享受和垄断了政治权利的人才真正的实现了几代中国人的梦想,他们绝对已经达到甚至超过欧美发达国家生活的水准。当然,另外一极的其他“普通老百姓”则是标准的第三世界贫穷国家的国民。来自官方背景的黑领对来自民间草根的白领的颠覆,体现了政治权力向自由经济领域的渗透和僭越,以政治权力篡夺经济权力。
这种食利自肥的经济身份使官方的超脱精神和公益基础遭到侵犯,合法性受到玷污,政治的伦理尊严荡然无存。官方由民众的仆从变成“民主”——民众的主子,由
公共利益的正义仲裁者演化为自身利益集团的代言人,从国家和社会的守夜人退化为自私卑鄙的盗窃者。这是一种极其危险的倾向。
白领阶层可以说是开放的,或者说穷人的孩子可以通过读书实现白领梦。
正因为如此,白领在大学扩招后人力资源充沛的中国急剧贬值。相对而言,黑领阶层则完全是封闭的,正因为封闭,才会奇货可居炙手可热。公共机构实际上已经成
为官僚权力集团把持的私家后院,普通人家的孩子要想进入这个群体,理论上说不是不可能,只能说——很渺茫。不错,公务员是公开招聘的,垄断官方企业的职位
也是面向社会招聘的,只要你拥护那个党,你就可以报名考试。
但地球人都知道这里面的规矩——潜规则,考不考得上并不取决于考试分数。黑领的特殊之处是已经走向组织化和正在走向世袭化,前者巩固,后者继承。在白领黯然陨落之后,黑领的低调崛起在全社会引发了一轮又一轮的考公务员热。同时,黑领也成为所有商家追逐的目标,他们比白领具有更真实更强悍的消费力。他们走到哪里,哪里就物价飞涨;他们对地产的投资,使农民失去了土地,使白领丧失了家园。当白领遇见黑领,立马被压出西装下面的“小”来。
今天,一个供职于夹缝状态私企的所谓白领,以他微薄的收入仅够维持温饱而已,消费对他来说已经是一个太过夸张和绝望的词语。不久前官商云集(没有几个身家低于千万)的两会上,一个黑领代表或是同情或是鄙夷地建议小白领们应该去卖肉——不是出卖自己的肉体,是卖猪肉。在这场席卷地球的金融风暴中,无数外企破产倒闭、业绩滑坡,覆巢之下,纷纷裁员降薪,白领们仓皇失业。与此相反,中国官有组织却财大气粗逆市飘红,令世界500 强为之羡慕,黑领们仍然可以毫无罪恶感地集体加薪。
近水楼台先得月,砸向黑领掌心的4万亿投资计划如同一针鸡血,使无数红了眼的黑领们激动得加额称庆——还是中国好、组织好啊。说实话,贫困潦倒的白领们从这4万亿民脂民膏中想捡点残羹剩饭也是痴心妄想。所以说,“孔乙己”这样卑微的白领如何能与“假洋鬼子”这样傲慢的黑领同日而语?如果说白领曾经掀起一股托福热、小资热的话,黑领的江湖则使传统国学和势利文化大热。易中天的阴谋学、王立群阎崇年的帝王学、于丹的犬儒学和马未都的收藏学等等,无不映照了黑领这个社会核心消费阶层的形成。
黑领的兴起说明,20年前的那场轰轰烈烈的反腐败反官倒运动之后,新兴知识群体在与权力群体博弈中已经完全丧失了主动权。权力经济终于在近10年从量变到质变,完成了对知识经济和自由经济的彻底颠覆。权力组织在文革后重新收复了对共和国的垄断话语权。近年来热映银屏的《激情燃烧的岁月》、《军歌嘹亮》、《金婚》和《天下兄弟》等剧,集中反映了文革时期第一代黑领的优裕生活。权力特权下的文革被营造被演绎得无比温馨富足和谐,根本看不到知识阶层生不如死和农民阶层食不果腹的悲惨灾难。
这种以主旋律色彩出现的怀旧情绪充满复辟邪恶和美化罪恶的企图。曾经的党校高材生、当代厚黑学大师冯仑老板毫不客气地把白领鄙视为“房奴”,一个“奴”字撕下了一群人看似体面的假领。诚然,白领没有任何社会权利,没有罢工权,没有选举权,没有话语权;他们没有权势,没有资本,没有门第。相反,黑领则是这个国家的上帝选民。
他们的房子票子车子等等除过老婆之外,都一概享受无偿配给,几乎不用跟“普通老百姓”们争来抢去的所谓市场发生任何关系。白领是如此脆弱而不堪一击,一套小小栖身的房子就可以将其压垮;而黑领是如此坚不可催固若金汤,一场导致无数孩子死亡的“三鹿”惨案,也未见一人因职务犯罪被追究法律责任,仅仅纪律处分了事。因为对立法权和司法权的把持,黑领群体成为名义上和实质上的共和国公民,他们普遍享受到一个共和国公民所应当享受的一切政治权利。
从基本人权、财产权、公民权、选举权和一切社
会福利,他们都应有尽有的得到了充分保护和满足。与之相反,日渐普遍和经济失宠的白领群体则无法享受到基本人权保证,更遑论公民权和社会福利。他们被官方
称之为与“公民”相对立的“普通老百姓”或者“群众”。相对于“共和国公民”而言,“普通老百姓”在政治层面和法律意义上,仅相当于“人畜”、“奴隶”或
者“机器人”。他们经常被官方作为十几亿的巨额国家财产来看待,说好听点叫作“劳动力资源”。其对外的称呼为“人民”,多用在“伤害中国人民感情”的时
候。白领的陨落代表着知识精英的穷途末路和理性精神的落败,黑领的兴盛代表着权力意识形态的扩张,和反知识重权力的血统论和阴谋论王者归来。
“知识贬值”必然带来“读书无用论”的盛行,
中国社会从此向封建资本主义进一步靠拢。社会文化日渐沙化和盐碱化,重归流氓文化和宫廷权谋黑幕政治的覆辙。黑领对白领的阻击和绞杀使构成未来社会主流的
新兴中产阶级胎死腹中,建立宪政公民社会的启蒙运动被迫土崩瓦解。这种财阀与权贵的合力扼杀使一个民族的创新能力和创造力严重退化直至丧失。社会结构和信
息结构进一步被凝固被肢解,青年一代被年迈保守的既得利益者压制封堵在社会最底层。
健康的社会流动和财富循环陷于停滞,推动社会
进步的活力和源泉被窒息被堵死。胜者为王的狼图腾文化、不择手段的官场权谋文化、暴殄天物的面子文化和崇高伟大的满清皇帝戏之所以大行其道,正映射着白领
规则的陨落与黑领规矩的升起,中国社会由知识和文明的艰难复苏,无可挽回地退回到野蛮与无知的权力通吃、弱肉强食中去。
人往高处走,水往低处流。在全社会的羡慕、嫉妒和仇视之中,黑领阶层一方面继续低调的巩固其社会地位(政治地位和经济地位),另一方面在完成原始积累后,他们开始悄然向新大陆挺进——携款外逃,或者投资移民,实现自己正式加入世界发达国家高级人类的梦想,同时也使自己的后代永远彻底的摆脱水深火热的中国。摘自胡记茶行《对现状的分析——挤不进去,你永远是穷人》:据官方统计, 2004年中国农民人均年收入2936元,按年人均纯收入低于668元的标准,中国农村绝对贫困人口为2610万人。如果按照世界上公认的人均1天1美元以下就属贫困的标准,我国目前还有2.1亿贫困人口。“八五”期间,公车车辆消费占到全部国家财政支出的38%,整个国家总计支出37960亿中的 37.58%用于供养行政公务人员;公款吃喝公费出国年花费每年达9000 亿元以上。
中国社会阶层分类:第一个阶层(也是处于最顶端的王者阶层)是
由几百个家族组成,他们拥有骇人听闻的财富,是这个国家的掌控者。在他们之下是第二个阶层——地方性的豪族,数量也许是几万家,这些人控制着地方的权力,
自然也拥有无与伦比的财产。第三个阶层是由公务员,事业单位人员、国企管理人员、垄断国企人员和私营企业主等这些人中的佼佼者以及顶级白领阶层等这些群体
中的人员组成。第四个阶层是生活比较安逸的一般民众,他们经济上还算比较宽裕,但是社会地位不高,对社会没有什么影响力。第五个阶层是由城市平民和农村中
生活比较好的农民组成。第六个阶层是贫困群体,也就是四亿没有购买能力的民众。第七个阶层是一亿没有财富的赤贫阶层,第八个阶层就是最后那一亿灾难性赤贫
的阶层。
2009年6月6日星期六
fedora10安装nginx并配置php
yum install nginx
安装php5
yum install lighttpd-fastcgi php-cli php-mysql php-gd php-imap php-ldap
php-odbc php-pear php-xml php-xmlrpc php-eaccelerator php-magickwand
php-magpierss php-mapserver php-mbstring php-mcrypt php-mhash php-mssql
php-shout php-snmp php-soap php-tidy
vi /etc/php.ini
添加
cgi.fix_pathinfo = 1
至文件末尾
vi /etc/rc.local
添加
/usr/bin/spawn-fcgi -a 127.0.0.1 -p 9000 -u nginx -g nginx -f /usr/bin/php-cgi -P /var/run/fastcgi-php.pid
至文件末尾
(这是配置FastCGI加入到默认启动)
配置nginx(以下都是修改 不是添加)
vi /etc/nginx/nginx.conf
(可选)
worker_processes 5;
keepalive_timeout 2;
(必选)
server {
listen 80;
server_name _;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root /usr/share/nginx/html;
index index.php index.html index.htm;
}
error_page 404 /404.html;
location = /404.html {
root /usr/share/nginx/html;
}
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1.sixxs.org;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
location ~ \.php$ {
root /usr/share/nginx/html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /usr/share/nginx/html$fastcgi_script_name;
include fastcgi_params;
}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
location ~ /\.ht {
deny all;
}
}
重启nginx即可。
感觉apache对php的内置支持的确更好用一点
2009年6月3日星期三
CVS 简单教程
版权声明:本文档遵循 FDL 版权发布,有关 FDL 的详细信息,请参考:
http://www.fsf.org.sixxs.org/copyleft/fdl.html
何伟平
CVS 是 Concurrent Version
System(并行版本系统)的缩写,用于版本管理.如果大家曾经参与过多人协作开发的项目,大家肯定有这样的痛苦经历:由于多个人同时修改同一个文件,
自己辛辛苦苦修改的程序被别人彻底删除了.另外,如果你的软件/程序已经发布了三个版本,而这时候用户需要你修改第二个版本的东西,也许你会因为只保留了
最新版本而痛哭流涕.还有就是你对程序做了一些修改,但是修改很少,你只想给远方的同事发一个两个版本之间的差别文件,这样可以免于邮箱不够大,网速太慢
之类的问题.为了解决类似这样的问题,以及诸如生成补丁文件,历史版本修改等,一帮黑客(褒义)在原先 Unix 体系里很成熟的 SCCS 和
RCS 的基础上,开发了 CVS.(SCCS:Source Code Control System,RCS:Revision Control
System)
CVS
的基本工作思路是这样的:在一台服务器上建立一个仓库,仓库里可以存放许多不同项目的源程序.由仓库管理员统一管理这些源程序.这样,就好象只有一个人在
修改文件一样.避免了冲突.每个用户在使用仓库之前,首先要把仓库里的项目文件下载到本地.用户做的任何修改首先都是在本地进行,然后用 cvs
命令进行提交,由 cvs 仓库管理员统一修改.这样就可以做到跟踪文件变化,冲突控制等等.
由于 CVS 是典型的 C/S 结构的软件,因此它也分成服务器端和客户端两部分.不过大多数 CVS 软件都把它们合二为一了.
结合文档和一些网上资源,我写一点非常简单的“速成”的教材.希望对大家有用.
下面是我的步骤和做法:
前提要求:
root 权限;
CVS软件,请找到相关的rpm,tgz,deb 等包装上,或者到
http://www.cvshome.org.sixxs.org/CVS/Dev/code
下载原程序编译安装,这里我不准备介绍它的安装,请参考CVS自身的文档安装.我使用Slackware的tgz包,安装的命令是
#installpkg cvs*.tgz
其他包请参考对应包管理工具的命令.
一定的系统资源,要有一定内存(32M就能工作得很好),要一定的磁盘空间,看你的项目的大小和多少而定.
架设CVS服务器:
建立 CVSROOT
目录,因为这里涉及到用户对CVSROOT里的文件读写的权限问题,所以比较简单的方法是建立一个组,然后再建立一个属于该组的帐户,而且以后有读写权限
的用户都要属于该组.假设我们建一个组叫cvs,用户名是cvsroot.建组和用户的命令如下
#groupadd cvs
#adduser cvsroot
生成的用户家目录在/home/cvsroot(根据自己的系统调整)
用 cvsroot 用户登陆,修改 /home/cvsroot (CVSROOT)的权限,赋与同组人有读写的权限:
$chmod 771 . (或者770应该也可以)
注意:这一部分工作是按照文档说明做的,是否一定需要这样没有试验,我会在做试验后在以后版本的教程说得仔细一点.如果您有这方面的经验请提供给我,谢谢.
建立CVS仓库,(仍然是 cvsroot 用户),用下面命令:
$cvs -d /home/cvsroot init
以root身份登陆,修改 /etc/inetd.conf(使用 xinetd 的系统没有此文件)和 /etc/services,
如果用的是 inetd 的系统,在 /etc/inetd.conf 里加入:
cvsserver stream tcp nowait root /usr/bin/cvs cvs -f --allow-root=/home/cvsroot pserver
说明:上面的行是单独一整行,/usr/bin/cvs 应该是你的cvs版本的命令路径,请根据自己的系统调整./home/cvsroot 是你建立的CVSROOT的路径,也请根据上面建立目录的部分的内容做调整.
如果是使用 xinetd 的系统,需要在 /etc/xinetd.d/ 目录下创建文件 cvspserver(此名字可以自己定义),内容如下:
# default: on
# description: The cvs server sessions;
service cvsserver
{
socket_type = stream
wait = no
user = root
server = /usr/bin/cvs
server_args = -f --allow-root=/cvsroot pserver
log_on_failure += USERID
only_from = 192.168.0.0/24
}
其中only_from是用来限制访问的,可以根据实际情况不要或者修改。修改该文件权限:
# chmod 644 cvspserver
在/etc/services里加入:
cvsserver 2401/tcp
说明:cvsserver 是任意的名称,但是不能和已有的服务重名,也要和上面修改 /etc/inetd.conf 那行的第一项一致.这里我用的是 CVS 的口令认证方式,CVS 还有其他认证方式,我没有做试验,如果您有经验,请补充,谢谢.
添加可以使用 CVS 服务的用户到 cvs 组:
以 root 身份修改 /etc/group,把需要使用 CVS 的用户名加到 cvs 组里,比如我想让用户 laser 和gumpwu 能够使用 CVS 服务,那么修改以后的 /etc/group 应该有下面这样一行:
cvs:x:105:laser,gumpwu
在你的系统上GID可能不是105,没有关系.主要是要把laser和gumpwu用逗号分隔开写在最后一个冒号后面.当然,象RedHat等分发版有类似linuxconf这样的工具的话,用工具做这件事会更简单些.
重起inetd使修改生效:
#killall -HUP inetd
如果使用的是 xinetd 的系统:
# /etc/rc.d/init.d/xined restart
这样服务器就设置完成了.我们接着搞客户端.
设置客户端
如果是 Linux(或者其他 *nix),客户端和服务器端的软件是一样的,如果是Win,MAC等平台,请到
http://www.loria.fr.sixxs.org/cgi-bin/molli/wilma.cgi/rel
找相应的客户端软件,这里我先说一下在 Linux(*nix)里怎么做:
设置环境变量CVSROOT:
$export CVSROOT=:pserver:laser@the_server_name:/home/cvsroot
注意:这里的pserver是访问方式,我在上面设置的是口令认证,所以这里是pserver,如果你的CVS服务器设置成别的访问模式,那么需要相应修
改.laser是可以使用
CVS服务器的用户名,这里可以根据你的设置修改,我在这个版本设置的是直接使用系统用户的口令文件,也就是说laser必须是CVS服务器上的合法用
户,这里当然有安全问题,CVS可以设置成为拥有自己的用户,我将在以后的版本里面增加这些内容,或者您也可以提供一些补充,或者直接读CVS的文
档.the_server_name是CVS服务器的名称或者IP地址,根据你的情况填写,/home/cvsroot是你的CVS服务器的
CVSROOT目录,根据你的CVS服务器设置做修改或者询问管理员.你可以把这行放到你的shell的profile里
(.bash_profile,.profile等)这样就不用每次敲一长串命令了.
登陆CVS服务器:
$ cvs login,这时候 cvs 会问你口令,请把你在 CVS 服务器上的口令敲进去,这里是 laser 在 CVS服务器上的系统用户的口令:
Passwd:xxxxxxxx
成功登陆后将在你的家目录建立一个 .cvspass 文件,以后就不用输入口令了.
好,客户端设置完成,简单吧.
管理 cvs 服务器
服务器可以用了,现在大家最关心的就是如何管理服务器,比如,我想让一些人有读和/或写 CVS 仓库的权限,但是不想给它系统权限怎么办呢?
不难,在 cvs 管理员用户(在我这里是 cvsroot 用户)的家目录里有一个 CVSROOT
目录,这个目录里有三个配置文件,passwd, readers, writers,我们可以通过设置这三个文件来配置 CVS
服务器,下面分别介绍这几个文件的作用:
passwd:cvs 用户的用户列表文件,它的格式很象 shadow 文件:
{cvs 用户名}:[加密的口令]:[等效系统用户名]
如果你希望一个用户只是 cvs 用户,而不是系统用户,那么你就要设置这个文件,刚刚安装完之后这个文件可能不存在,你需要以 cvs
管理员用户手工创建,当然要按照上面格式,第二个字段是该用户的加密口令,就是用 crypt (3)
加密的,你可以自己写一个程序来做加密,也可以用我介绍的偷懒的方法:先创建一个系统用户,名字和 cvs 用户一样,口令就是准备给它的 cvs
用户口令,创建完之后从 /etc/shadow
把该用户第二个字段拷贝过来,然后再把这个用户删除.这个方法对付数量少的用户比较方便,人一多就不合适了,而且还有冲突条件(race
condition)的安全隐患,还要 root 权限,实在不怎么样.不过权益之计而已.写一个小程序并不难,可以到 linuxforum
的编程版搜索一下,有个朋友已经写了一个贴在上面了.
第三个字段就是等效系统用户名,实际上就是赋与一个 cvs 用户一个等效的系统用户的权限,看下面的例子你就明白它的功能了.
readers:有 cvs 读权限的用户列表文件.就是一个一维列表.在这个文件中的用户对 cvs只有读权限.
writers:有 cvs 写权限的用户的列表文件.和 readers 一样,是一个一维列表.在这个文件中的用户对 cvs 有写权限.
上面三个文件在缺省安装的时候可能都不存在,需要我们自己创建,好吧,现在还是让我们用一个例子来教学吧.假设我们有下面几个用户需要使用 cvs:
laser, gumpwu, henry, betty, anonymous.
其中 laser 和 gumpwu 是系统用户,而 henry, betty, anonymous 我们都不想给系统用户权限,并且 betty
和 anonymous 都是只读用户,而且 anonymous 更是连口令都没有.那么好,我们先做一些准备工作,先创建一个 cvspub
用户,这个用户的责任是代表所有非系统用户的 cvs 用户读写 cvs 仓库.
#adduser
...
然后编辑 /etc/group,令 cvspub 用户在 cvs 组里,同时把其它有系统用户权限的用户加到 cvs 组里.(见上文)
然后编辑 cvs 管理员家目录里 CVSROOT/passwd 文件,加入下面几行:
laser:$xxefajfka;faffa33:cvspub
gumpwu:$ajfaal;323r0ofeeanv:cvspub
henry:$fajkdpaieje:cvspub
betty:fjkal;ffjieinfn/:cvspub
anonymous::cvspub
注意:上面的第二个字段(分隔符为 :)是密文口令,你要用程序或者用我的土办法生成.
编辑 readers 文件,加入下面几行:
anonymous
betty
编辑 writer 文件,加入下面几行:
laser
gumpwu
henry
这样就 ok 了,你再用几个用户分别登陆测试,就会发现一切都 ok 了.这里面的原理和说明我想就不多说了,其实很简单,和系统管理用户的概念是一样的.
现在服务器和客户端都设置好了,那么怎么用呢,我在这里写一个最简单的(估计也是最常用的)命令介绍:
首先,建立一个新的CVS项目,一般我们都已经有一些项目文件了,这样我们可以用下面步骤生成一个新的CVS项目:
进入到你的已有项目的目录,比如叫 cvstest:
$cd cvstest
运行命令:
$cvs import -m "this is a cvstest project" cvstest v_0_0_1 start
说明:import 是cvs的命令之一,表示向cvs仓库输入项目文件.
-m参数后面的字串是描述文本,随便写些有意义的东西,如果不加 -m 参
数,那么cvs会自动运行一个编辑器(一般是vi,但是可以通过修改环境变量
EDITOR来改成你喜欢用的编辑器.)让你输入信息,
cvstest 是项目名称(实际上是仓库名,在CVS服务器上会存储在以这个名字
命名的仓库里.)
v_0_0_1是这个分支的总标记.没啥用(或曰不常用.)
start 是每次 import 标识文件的输入层次的标记,没啥用.
这样我们就建立了一个CVS仓库了,然后,我们可以把这个测试项目的文件删除.试验一下如何从仓库获取文件.这里我假设上面的所有客户端工作你都已经做过了.
运行下面的命令:
$cvs checkout cvstest
从仓库中检索出cvstest项目的源文件.
如果你已经做过一次checkout了,那么不需要重新checkout,只需要进入cvstest项目的目录,更新一把就行了:
$cd cvstest
$cvs update
一下即可.又或者你不想直接更新,只是想看看有没有更新的东西,那么:
$cvs status
这时后会打印出一长串状态报告(你可能需要用类似less这样的命令分页显示,或者定向到一个输出文件里慢慢看.),对项目中的每个文件有一份状态报告,类似这样:
===================================================================
File: foo.c Status: Up-to-date
Working revision: 1.1.1.1 'Some Date'
Repository revision: 1.2 /home/cvsroot/cvstest/foo.c,v
Sticky Tag: (none)
Sticky Date: (none)
Sticky Options: (none)
这里最重要的就是 Status 栏,这里总共可能有四种状态:
Up-to-date:表明你要到的文件是最新的.
Locally Modified:表明你曾经修改过该文件,但还没有提交,你的版本比仓库里的新.
Needing Patch:表明有个哥们已经修改过该文件并且已经提交了!你的版本比仓库里的旧.
Needs Merge:表明你曾经修改过该文件,但是偏偏有个不识相的也修改了这个文件,而且还提交给仓库了!
如果你只是想保持软件的同步的话(象我),那么上面的东西就足够用了.可是如果多人协作开发项目的话,可就不是了这么简单了.当你参加项目,维护文件时,就需要更多命令,比如说你我都是某 nasdaq 项目的开发人员:
1,你对某个文件做了修改,比如说改了ceo.c,加了一行程序:printf("where can I find VC to cheat!");
改完之后你要把修改提交给仓库,用命令:
$cvs commit -m "add a complain" ceo.c
或者就是:
$cvs commit -m "worry about money"
让cvs帮你检查哪个文件需要提交.
2,当我开始干活的时候,可能我先:
$cvs status
一把,这时候我会看到:
==================================================================
File: ceo.c Status: Needing Patch
Working revision: 1.1.1.1 'Some Date'
Repository revision: 1.2 /home/cvsroot/nastaq/ceo.c,v
Sticky Tag: (none)
Sticky Date: (none)
Sticky Options: (none)
于是我知道有人改了ceo.c,于是我就:
$cvs update ceo.c
或者干脆:
$cvs update
把ceo.c这个文件更新为最新版本,然后再干活.然后提交.
如果这天你修改了coo.c,加了一行 puts("how about another kind of bragging?");
并且提交了,但是这时候我已经 $cvs status 过了,就是说我不知道你的修改.
而我加了一行printf("You must shamelessly and seems knowingness to act as a coo");
并且傻乎乎地提交:
$cvs commit coo.c
这时候,CVS会告诉我
cvs commit: Examing .
cvs server: Up-to-date check failed for 'coo.c'
cvs [server aborted]: correct above error first!
于是我知道有个狗屎在我修改文件的当口做了提交,于是我
$cvs update
这时cvs会报告:
RCS file: /home/cvsroot/nasdaq/coo.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
Merging differences between 1.1.1.1 and 1.2 into coo.c
rcsmerge: warning: conflicts during merge
cvs update: conflicts found in coo.c
C coo.c
告诉你coo.c有版本冲突,于是我编辑coo.c,这时一般文件里看起来象这样:
...
printf("You must shamelessly and seems knowingness to act as a coo");
<<<<<<< foo.c
=======
...
puts("how about another kind of bragging?");
>;>;>;>;>;>;>; 1.2
...
于是我把上面改成:
printf("You must shamelessly and seems knowingness to act as a coo");
puts("how about another kind of bragging?");
然后
$cvs commit -m "merged" coo.c
于是下回你再更新的时候就有新的补钉要打...如此往复,直到完成所有修改.
不过这里有一些要注意的地方就是删除程序,如果你删掉一行对你可能没有用的程序
puts("to be honest"); 而我不想删除(因为我有用),而我不知情地直接:
$cvs update
了,那么我的这行程序也完蛋了,所以这里我们要注意所有开发人员的协调,千万不要乱删东西,大不了用
#if 0
#endif
宏定义对括起来.实在要删东西,那最好先标记一个版本:
$cvs tag v_0_0_1
然后你可以发布并删除你自己的工作目录里这个版本的文件(注意:不是删除仓库里的.):
$cvs release -d nasdaq
然后你再生成一个新分支:
$cvs rtag -b -r v_0_0_1 v_0_0_1_1 nasdaq
然后再建立v_0_0_1_1的分支
$cvs checkout -r v_0_0_1_1 nasdaq
编辑并修改这个分支的文件,这样的做法比较好.
不过要注意的是,新标记和新分支的建立最好由项目的管理人员负责,否则每个人都做一个分支,那么仓库就太乱了.因此,比较的开发人员之间的直接沟通是不能
忽略的.一般来说,在互联网上的标准模式是有一个管理员(可能自己并不写程序),有一个邮递列表,大家都在邮递列表上交流看法和做各种决议.当形成决议之
后,管理员做一个新版本的标记.以此循环.
还有一些命令,比如要增加一个文件 garbage_china_concept_stocks_list:
$cvs add garbage_china_concept_stocks_list
然后还要:
$cvs commit garbage_china_concert_stocks_list
看起来有点象数据库里的事务?的确是这样.CVS维护着一个本地的参考文件(在CVS/Entries里),这样提交的时候就可以一次地把所有改变放到服务器端,这样也更安全.同样,如果想删除文件 bankrupted_web_site:
$rm bankrupted_web_site
$cvs remove bankrupted_web_site
$cvs commit bankrupted_web_site
3,一些小技巧:
$Header$ 标记:把这个标记放在文件的任何地方都会被 cvs 替换成最后修改的 cvs 用户名,该文件当前版本号,最后修改时间,该文件的 cvs 仓库路径,看起来象下面这个样子:
// $Header: /home/cvsroot/simhost/simhost.cpp,v 1.2 2001/04/20 08:26:10 jqliu Exp $
一般我们把它放在开头,这样对程序员修改文件非常便利,很多时候你只要看一眼开头就知道文件是否最新.
$Id$标记:把这个标记放在文件的任何地方都会被 cvs 替换成最后修改的 cvs 用户名,该文件当前版本号,最后修改时间,该文件的 cvs 仓库路径,看起来象下面这个样子:
$Id: simhost.cpp,v 1.3 2001/04/24 02:27:36 simhost Exp $
好了,上面所有的东西,估计就是我们用cvs时80%情况下用的命令和内容,包括文件的更新,提交,冲突的解决,分支的派生,增删文件等.实际上cvs的
功能之强大,远远超出我在这里描述的内容,我这个"速成"也就管不了太多了,希望随着时间的推移,我们能够更加有效地使用CVS.也希望大家能够不断补充
这篇文章,最后能够成为手册,而不仅仅是速成.当然,还要更多地参考别的文档.
参考资料:
http://www.loria.fr.sixxs.org/cgi-bin/molli/wilma.cgi/doc.865331095.html
http://www.loria.fr.sixxs.org/~molli/cvs/doc/cvs_toc.html