歌曲:悟空
演唱:叶坳栖
作词:尹杰
作曲:叶坳栖
☆LRC:明奇胖胖
QQ:346716061☆
不管你们是老夫少妻 还是姐弟搭配
只要你们之间有爱情 没有别的目的
为了美貌用自己多金 换对方来拜金
如果你有一天没有金 只能得到无情
为了金钱用自己的美 背叛真情真心
等到有一天青春消逝 后悔没有意义
人生苦短 耗尽一生只为假装和欺骗
悲欢聚散 虚荣一时得到永远的孤单
谁都期盼 找到一个不离不弃的港湾
快乐短暂 为了一个昙花一现的快感
丢了一生一世的幸福
不管你们是老夫少妻 还是姐弟搭配
只要你们之间有爱情 没有别的目的
为了美貌用自己多金 换对方来拜金
如果你有一天没有金 只能得到无情
为了金钱用自己的美 背叛真情真心
等到有一天青春消逝 后悔没有意义
人生苦短 耗尽一生只为假装和欺骗
悲欢聚散 虚荣一时得到永远的孤单
谁都期盼 找到一个不离不弃的港湾
快乐短暂 为了一个昙花一现的快感
丢了一生一世的幸福
☆LRC:明奇胖胖
QQ:346716061☆
人生苦短 耗尽一生只为假装和欺骗
悲欢聚散 虚荣一时得到永远的孤单
谁都期盼 找到一个不离不弃的港湾
快乐短暂 为了一个昙花一现的快感
丢了一生一世的幸福
你觉得值得吗
你觉得值得吗
演唱:叶坳栖
作词:尹杰
作曲:叶坳栖
☆LRC:明奇胖胖
QQ:346716061☆
不管你们是老夫少妻 还是姐弟搭配
只要你们之间有爱情 没有别的目的
为了美貌用自己多金 换对方来拜金
如果你有一天没有金 只能得到无情
为了金钱用自己的美 背叛真情真心
等到有一天青春消逝 后悔没有意义
人生苦短 耗尽一生只为假装和欺骗
悲欢聚散 虚荣一时得到永远的孤单
谁都期盼 找到一个不离不弃的港湾
快乐短暂 为了一个昙花一现的快感
丢了一生一世的幸福
不管你们是老夫少妻 还是姐弟搭配
只要你们之间有爱情 没有别的目的
为了美貌用自己多金 换对方来拜金
如果你有一天没有金 只能得到无情
为了金钱用自己的美 背叛真情真心
等到有一天青春消逝 后悔没有意义
人生苦短 耗尽一生只为假装和欺骗
悲欢聚散 虚荣一时得到永远的孤单
谁都期盼 找到一个不离不弃的港湾
快乐短暂 为了一个昙花一现的快感
丢了一生一世的幸福
☆LRC:明奇胖胖
QQ:346716061☆
人生苦短 耗尽一生只为假装和欺骗
悲欢聚散 虚荣一时得到永远的孤单
谁都期盼 找到一个不离不弃的港湾
快乐短暂 为了一个昙花一现的快感
丢了一生一世的幸福
你觉得值得吗
你觉得值得吗
由于SourceForge网站被封,导致很多程序员常用的开发框架都无法下载了,工作和学习非常不方便,下面教大家一个简单的下载sourceforge上面开源软件的办法:
http://mirror.optus.net/sourceforge/
访问如上URL地址,这是一个sourceforge的下载镜像站点,按照字母顺序分目录列出来sourceforge上面所有的软件下载了,我们可以按目录一级一级找到自己要下载的软件,例如:
我要下载Hibernate,那么寻找 /h/hi/hibernate 目录就找到了,该目录下面是所有Hibernate相关软件各个版本的下载地址:
http://mirror.optus.net/sourceforge/h/hi/hibernate/
再例如我要下载Spring也一样,寻找 /s/sp/springframework 目录,即:
http://mirror.optus.net/sourceforge/s/sp/springframework/
如果你想下载JBoss Seam和JBoss应用服务器的话,是下面这个目录:
http://mirror.optus.net/sourceforge/j/jb/jboss/
这个镜像的下载速度不错噢,经过测试每秒有60KB的稳定下载速度。
http://mirror.optus.net/sourceforge/
访问如上URL地址,这是一个sourceforge的下载镜像站点,按照字母顺序分目录列出来sourceforge上面所有的软件下载了,我们可以按目录一级一级找到自己要下载的软件,例如:
我要下载Hibernate,那么寻找 /h/hi/hibernate 目录就找到了,该目录下面是所有Hibernate相关软件各个版本的下载地址:
http://mirror.optus.net/sourceforge/h/hi/hibernate/
再例如我要下载Spring也一样,寻找 /s/sp/springframework 目录,即:
http://mirror.optus.net/sourceforge/s/sp/springframework/
如果你想下载JBoss Seam和JBoss应用服务器的话,是下面这个目录:
http://mirror.optus.net/sourceforge/j/jb/jboss/
这个镜像的下载速度不错噢,经过测试每秒有60KB的稳定下载速度。
姜源 说:
http://www.scribd.com/doc/263139/VIM-for-PHP-Programmers
姜源 说:
这个slide介绍了一些用vim写php的技艺。
姜源 说:
技巧
姜源 说:
但如果你希望用那些auto complete比较好的功能还是别用vi了。
向东 xiangdong.org 说:
hao ..
姜源 说:
vi是一个超级editor不是一个ide
姜源 说:
以前写php的时候我只用editplus
姜源 说:
基本是开着手册。
姜源 说:
很少用自动完成功能。
向东 xiangdong.org 说:
懒人啊,呵呵,我用zend咯。。
http://www.scribd.com/doc/263139/VIM-for-PHP-Programmers
姜源 说:
这个slide介绍了一些用vim写php的技艺。
姜源 说:
技巧
姜源 说:
但如果你希望用那些auto complete比较好的功能还是别用vi了。
向东 xiangdong.org 说:
hao ..
姜源 说:
vi是一个超级editor不是一个ide
姜源 说:
以前写php的时候我只用editplus
姜源 说:
基本是开着手册。
姜源 说:
很少用自动完成功能。
向东 xiangdong.org 说:
懒人啊,呵呵,我用zend咯。。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script language="javascript" src="template.js"></script>
<script language="javascript">
</script>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>js测试</title>
</head>
<body>
<textarea name="template_jst" id="template_jst" cols="44" rows="22">
Hello ${customer.first} ${customer.last}.<br/>
Your shopping cart has ${products.length} item(s):
<table>
<tr><td>Name</td>
<td>Description</td>
<td>Price</td>
<td>Quantity & Alert</td>
</tr>
{for p in products}
<tr><td>${p.name|capitalize}</td><td>${p.desc}</td>
<td>$${p.price}</td><td>${p.quantity} :
${p.alert|default:""|capitalize}</td>
</tr>
{forelse}
<tr><td colspan="4">No products in your cart.</tr>
{/for}
</table>
{if customer.level == "gold"}
We love you! Please check out our Gold Customer specials!
{else}
Become a Gold Customer by buying more stuff here.
{/if}
</textarea>
<div>
<textarea name="jsData" id="jsData" cols="44" rows="21">
var data = {
products : [ { name: "Linu", desc: "computer",
price: 1000, quantity: 100, alert:null },
{ name: "ipod", desc: "music player",
price: 200, quantity: 200, alert:"on sale now!" },
{ name: "cinema display", desc: "screen",
price: 800, quantity: 300, alert:"best deal!" } ],
customer : { first: "John", last: "Public", level: "gold" }
};
</textarea>
</div>
<hr/>
Output:
<div id="output" name="dfjdk">test</div>
</body>
<script language="javascript">
var dataTextarea = document.getElementById("jsData");
var outputEl = document.getElementById("output");
eval(dataTextarea.value);
//outputEl.innerHTML = TrimPath.processDOMTemplate("template_jst", data);
outputEl.innerHTML =TrimPath.parseTemplate(document.getElementById("template_jst").value, "template_jst").process(data);
</script>
</html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script language="javascript" src="template.js"></script>
<script language="javascript">
</script>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>js测试</title>
</head>
<body>
<textarea name="template_jst" id="template_jst" cols="44" rows="22">
Hello ${customer.first} ${customer.last}.<br/>
Your shopping cart has ${products.length} item(s):
<table>
<tr><td>Name</td>
<td>Description</td>
<td>Price</td>
<td>Quantity & Alert</td>
</tr>
{for p in products}
<tr><td>${p.name|capitalize}</td><td>${p.desc}</td>
<td>$${p.price}</td><td>${p.quantity} :
${p.alert|default:""|capitalize}</td>
</tr>
{forelse}
<tr><td colspan="4">No products in your cart.</tr>
{/for}
</table>
{if customer.level == "gold"}
We love you! Please check out our Gold Customer specials!
{else}
Become a Gold Customer by buying more stuff here.
{/if}
</textarea>
<div>
<textarea name="jsData" id="jsData" cols="44" rows="21">
var data = {
products : [ { name: "Linu", desc: "computer",
price: 1000, quantity: 100, alert:null },
{ name: "ipod", desc: "music player",
price: 200, quantity: 200, alert:"on sale now!" },
{ name: "cinema display", desc: "screen",
price: 800, quantity: 300, alert:"best deal!" } ],
customer : { first: "John", last: "Public", level: "gold" }
};
</textarea>
</div>
<hr/>
Output:
<div id="output" name="dfjdk">test</div>
</body>
<script language="javascript">
var dataTextarea = document.getElementById("jsData");
var outputEl = document.getElementById("output");
eval(dataTextarea.value);
//outputEl.innerHTML = TrimPath.processDOMTemplate("template_jst", data);
outputEl.innerHTML =TrimPath.parseTemplate(document.getElementById("template_jst").value, "template_jst").process(data);
</script>
</html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>一个使用到for...in循环的Javascript示例</title>
</head>
<body>
<script type="text/javascript">
var data = {
products : [ { name: "Linu", desc: "computer",
price: 1000, quantity: 100, alert:null },
{ name: "ipod", desc: "music player",
price: 200, quantity: 200, alert:"on sale now!" },
{ name: "cinema display", desc: "screen",
price: 800, quantity: 300, alert:"best deal!" } ],
customer : { first: "John", last: "Public", level: "gold" }
};
function isArray(a) {
if(typeof a =="undefined"||null==a)
{
return false;
}
else
{
return a.sort ? true : false;
}
}
function printObj(obj,depth,Attr)
{
if(typeof depth=="undefined"){depth=0;}
if(typeof Attr=="undefined"){Attr="";}
/*
var space="";
for(var i=0;i<=depth;i++)
{
space+=" "
}
if(""!=Attr)
{
document.write(space+Attr+":<br />");
}
*/
if(isArray(obj))
{
for(var i=0;i<obj.length;i++)
{
printObj(obj[i],depth++,i);
}
}
else{
if(typeof obj=="undefined")
{
}else if(typeof obj=="string"||typeof obj=="number" ||typeof obj=="boolean")
{
//document.write(space+" "+obj+"<br />");
document.write(" "+obj+"<br />");
}else
{
for(var p in obj)
{
var eachValue=obj[p];
printObj(eachValue,depth++,p);
}
}
}
}
printObj(data);
</script>
</body>
</html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>一个使用到for...in循环的Javascript示例</title>
</head>
<body>
<script type="text/javascript">
var data = {
products : [ { name: "Linu", desc: "computer",
price: 1000, quantity: 100, alert:null },
{ name: "ipod", desc: "music player",
price: 200, quantity: 200, alert:"on sale now!" },
{ name: "cinema display", desc: "screen",
price: 800, quantity: 300, alert:"best deal!" } ],
customer : { first: "John", last: "Public", level: "gold" }
};
function isArray(a) {
if(typeof a =="undefined"||null==a)
{
return false;
}
else
{
return a.sort ? true : false;
}
}
function printObj(obj,depth,Attr)
{
if(typeof depth=="undefined"){depth=0;}
if(typeof Attr=="undefined"){Attr="";}
/*
var space="";
for(var i=0;i<=depth;i++)
{
space+=" "
}
if(""!=Attr)
{
document.write(space+Attr+":<br />");
}
*/
if(isArray(obj))
{
for(var i=0;i<obj.length;i++)
{
printObj(obj[i],depth++,i);
}
}
else{
if(typeof obj=="undefined")
{
}else if(typeof obj=="string"||typeof obj=="number" ||typeof obj=="boolean")
{
//document.write(space+" "+obj+"<br />");
document.write(" "+obj+"<br />");
}else
{
for(var p in obj)
{
var eachValue=obj[p];
printObj(eachValue,depth++,p);
}
}
}
}
printObj(data);
</script>
</body>
</html>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>无标题文档</title>
</head>
<body>
<div id = "contentdiv">111</div>
</body>
<script language="javascript">
var htmls="hello the world";
alert(document.getElementById('contentdiv').innerHTML);//HTML大写,否则调试不通过啊,必须让div加载后调用该函数
document.getElementById('contentdiv').innerHTML=htmls;
</script>
</html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>无标题文档</title>
</head>
<body>
<div id = "contentdiv">111</div>
</body>
<script language="javascript">
var htmls="hello the world";
alert(document.getElementById('contentdiv').innerHTML);//HTML大写,否则调试不通过啊,必须让div加载后调用该函数
document.getElementById('contentdiv').innerHTML=htmls;
</script>
</html>
老婆有一个优点,那就是智力超群。她有着超常的判断力和逻辑思维能力,常作惊人之语,让我佩服得五体投地。生活虽然平淡,但她的妙语时不时能给我一点意想不到的惊喜,为了和大家分享我的惊喜,特地总结了一下她比较著名的言论,举出最让我佩服的十大例子:
1.有一段时间我打她呼机她总是不回电,问她,她说:“我把呼机关了。”“为什么要把呼机关掉?”“公司常打我呼机叫我加班,我关了呼机,他们就呼不到我了。”
2.后来她买了一个手机,有一次她出门忘了带手机,从街上打公用电话给我:“老公快帮我给小芳打个电话,告诉她到麦当劳门口等我。”“你自己为什么不打?”“我手机没带呀!”
3.有一次看到地摊上卖莲蓬,老婆问:“怎么卖?”答:“一块一个。”“这么贵啊,三块两个卖不卖?”
4.有一次我和她出门,两个人只带了一把家门钥匙,她要去菜场,让我先回家,把钥匙留给她。我问她:“为什么要把钥匙留给你啊?”她说:“这样等会儿我回家,你就不用下来给我开门了。”
5.有一次听录音机,她一不小心按了录音按钮,我叫道:“快停掉,你把带子上东西抹掉了!”她不去按录音机却上来捂我的嘴,事后她解释道:“只要我们不发声音,带子上的内容不就抹不掉了。”
6.看电视新闻看到一半,她说:“快帮我按一下暂停,我要去洗手间!”
7.她说:“唉,明天又停电,什么事也做不成,只好躺在床上看一天电视了。”
8.唱卡拉OK,她用电视机摇控器上的选台按钮来选歌曲,都按出电视新闻来了,她还不明白:“为什么王菲的歌要配警察破案的画面?”
9.两个人搬电脑,她说:“这么重啊,你为什么搬之前不先删掉点东西?”
10.最后我把上面写的给她看,本以为她会不好意思笑的,不料她看了两遍,抬起头迷惑不解地问我:“怎么了,我说错什么了吗?”
1.有一段时间我打她呼机她总是不回电,问她,她说:“我把呼机关了。”“为什么要把呼机关掉?”“公司常打我呼机叫我加班,我关了呼机,他们就呼不到我了。”
2.后来她买了一个手机,有一次她出门忘了带手机,从街上打公用电话给我:“老公快帮我给小芳打个电话,告诉她到麦当劳门口等我。”“你自己为什么不打?”“我手机没带呀!”
3.有一次看到地摊上卖莲蓬,老婆问:“怎么卖?”答:“一块一个。”“这么贵啊,三块两个卖不卖?”
4.有一次我和她出门,两个人只带了一把家门钥匙,她要去菜场,让我先回家,把钥匙留给她。我问她:“为什么要把钥匙留给你啊?”她说:“这样等会儿我回家,你就不用下来给我开门了。”
5.有一次听录音机,她一不小心按了录音按钮,我叫道:“快停掉,你把带子上东西抹掉了!”她不去按录音机却上来捂我的嘴,事后她解释道:“只要我们不发声音,带子上的内容不就抹不掉了。”
6.看电视新闻看到一半,她说:“快帮我按一下暂停,我要去洗手间!”
7.她说:“唉,明天又停电,什么事也做不成,只好躺在床上看一天电视了。”
8.唱卡拉OK,她用电视机摇控器上的选台按钮来选歌曲,都按出电视新闻来了,她还不明白:“为什么王菲的歌要配警察破案的画面?”
9.两个人搬电脑,她说:“这么重啊,你为什么搬之前不先删掉点东西?”
10.最后我把上面写的给她看,本以为她会不好意思笑的,不料她看了两遍,抬起头迷惑不解地问我:“怎么了,我说错什么了吗?”
PHP作为一种服务器端的脚本语言,象编写简单,或者是复杂的动态网页这样的任务,它完全能够胜任。但事情不总是如此,有时为了实现某个功能,必须借助于操作系统的外部程序(或者称之为命令),这样可以做到事半功倍。
那么,是否可以在PHP脚本中调用外部命令呢?如果能,如何去做呢?有些什么方面的顾虑呢?相信你看了本文后,肯定能够回答这些问题了。
是否可以?
答案是肯定的。PHP和其它的程序设计语言一样,完全可以在程序内调用外部命令,并且是很简单的:只要用一个或几个函数即可。
阅读全文
那么,是否可以在PHP脚本中调用外部命令呢?如果能,如何去做呢?有些什么方面的顾虑呢?相信你看了本文后,肯定能够回答这些问题了。
是否可以?
答案是肯定的。PHP和其它的程序设计语言一样,完全可以在程序内调用外部命令,并且是很简单的:只要用一个或几个函数即可。

背景:经blockips实践%config(noreplace) /usr/local/nginx/conf/blockips.conf,在安装时有/usr/local/nginx/conf/blockips.conf,不会覆盖原来的,而是新起文件名:/usr/local/nginx/conf/blockips.conf.rpmnew ,在删这个rpm包时,rpm -e blockips 会将原来的没有被覆盖的文件/usr/local/nginx/conf/blockips.conf挪动为:/usr/local/nginx/conf/blockips.conf.rpmsave 。也就是说安装时不覆盖,生成新文件.rpmnew,卸载时那个安装时没有覆盖的文件挪动为.rpmsave。
[实践OK]blockips打包里实践得出来的。还发现如果和即将安装的一样的时候,是不会作上述重命名的,直接就安装上了,也就是说安装前做了比对操作!
实践也证明了上面的一个情况,一是noreplace会比对不一样给生成新的.rpmnew,卸载RPM包时会将原来没覆盖的文件给挪为.rpmsave,如果相同则直接覆盖,不做前面这些操作。
#rpm -ihv blockips-1.0.0-220622153009.el7.x86_64.rpm
Verifying... ################################# [100%]
准备中... ################################# [100%]
正在升级/安装...
1:blockips-1.0.0-220622153009.el7 ################################# [100%]
警告:/usr/local/nginx/conf/blockips.conf 已建立为 /usr/local/nginx/conf/blockips.conf.rpmnew
警告:/usr/local/nginx/conf/vhosts/blockipsvc.conf 已建立为 /usr/local/nginx/conf/vhosts/blockipsvc.conf.rpmnew
rpm -e blockips
警告:/usr/local/nginx/conf/vhosts/blockipsvc.conf 已另存为 /usr/local/nginx/conf/vhosts/blockipsvc.conf.rpmsave
警告:/usr/local/nginx/conf/blockips.conf 已另存为 /usr/local/nginx/conf/blockips.conf.rpmsave
ls -1 /usr/local/nginx/conf/blockips.conf.rpm*
/usr/local/nginx/conf/blockips.conf.rpmnew #rpm包安装时发现同名配置,给安装包里的重新命名为.rpmnew
/usr/local/nginx/conf/blockips.conf.rpmsave #卸载rpm包前因文件名内容不一样没有被覆盖的文件给重新命令为.rpmsave
ls -1 /usr/local/nginx/conf/vhosts/blockipsvc.conf.rpm*
/usr/local/nginx/conf/vhosts/blockipsvc.conf.rpmnew
/usr/local/nginx/conf/vhosts/blockipsvc.conf.rpmsave
上面的实践来源:https://jackxiang.com/post/11406/
In addition to the marked directories, the standard Linux documentation directories, such as /usr/share/man, are automatically assumed to be documentation directories.
Similar to the %doc directive, the %config directive marks a file as configuration. For example:
%files
/sbin/ypbind
%config /etc/rc.d/init.d/*
%config /etc/yp.conf
%doc README NEWS
A special option to the %config directive, noreplace, tells RPM not to overwrite, or replace a configuration file. For example:
%files
/sbin/ypbind
%config /etc/rc.d/init.d/*
%config(noreplace) /etc/yp.conf
%doc README NEWS
Use this option to help protect local modifications. If you use %config(noreplace), the file will not overwrite an existing file that has been modified. If the file has not been modified on disk, the rpm command will overwrite the file. But, if the file has been modified on disk, the rpm command will copy the new file with an extra file-name extension of .rpmnew.
Similarly, %config(missingok) means that the file does not have to exist on disk. You can use this modifier for files or links that are created during the %post scripts but will need to be removed if the package is removed.
Another special modifier, %ghost, tells the rpm command that the file should not be included in the package. You can use this to name the needed attributes for a file that the program, when installed, will create. For example, you may want to ensure that a program’s log file has certain attributes.
From:https://docs.fedoraproject.org/ro/Fedora_Draft_Documentation/0.1/html/RPM_Guide/ch09s05s03.html
强制删除所有rpm包:
RPM包常用参数 (备忘用)
1.安装一个包
# rpm -ivh
2.升级一个包
# rpm -Uvh
3.移走一个包
# rpm -e
4.安装参数
--force 即使覆盖属于其它包的文件也强迫安装
--nodeps 如果该RPM包的安装依赖其它包,即使其它包没装,也强迫安装。
5.查询一个包是否被安装
# rpm -q < rpm package name>
6.得到被安装的包的信息
# rpm -qi < rpm package name>
阅读全文
[实践OK]blockips打包里实践得出来的。还发现如果和即将安装的一样的时候,是不会作上述重命名的,直接就安装上了,也就是说安装前做了比对操作!
实践也证明了上面的一个情况,一是noreplace会比对不一样给生成新的.rpmnew,卸载RPM包时会将原来没覆盖的文件给挪为.rpmsave,如果相同则直接覆盖,不做前面这些操作。
#rpm -ihv blockips-1.0.0-220622153009.el7.x86_64.rpm
Verifying... ################################# [100%]
准备中... ################################# [100%]
正在升级/安装...
1:blockips-1.0.0-220622153009.el7 ################################# [100%]
警告:/usr/local/nginx/conf/blockips.conf 已建立为 /usr/local/nginx/conf/blockips.conf.rpmnew
警告:/usr/local/nginx/conf/vhosts/blockipsvc.conf 已建立为 /usr/local/nginx/conf/vhosts/blockipsvc.conf.rpmnew
rpm -e blockips
警告:/usr/local/nginx/conf/vhosts/blockipsvc.conf 已另存为 /usr/local/nginx/conf/vhosts/blockipsvc.conf.rpmsave
警告:/usr/local/nginx/conf/blockips.conf 已另存为 /usr/local/nginx/conf/blockips.conf.rpmsave
ls -1 /usr/local/nginx/conf/blockips.conf.rpm*
/usr/local/nginx/conf/blockips.conf.rpmnew #rpm包安装时发现同名配置,给安装包里的重新命名为.rpmnew
/usr/local/nginx/conf/blockips.conf.rpmsave #卸载rpm包前因文件名内容不一样没有被覆盖的文件给重新命令为.rpmsave
ls -1 /usr/local/nginx/conf/vhosts/blockipsvc.conf.rpm*
/usr/local/nginx/conf/vhosts/blockipsvc.conf.rpmnew
/usr/local/nginx/conf/vhosts/blockipsvc.conf.rpmsave
上面的实践来源:https://jackxiang.com/post/11406/
In addition to the marked directories, the standard Linux documentation directories, such as /usr/share/man, are automatically assumed to be documentation directories.
Similar to the %doc directive, the %config directive marks a file as configuration. For example:
%files
/sbin/ypbind
%config /etc/rc.d/init.d/*
%config /etc/yp.conf
%doc README NEWS
A special option to the %config directive, noreplace, tells RPM not to overwrite, or replace a configuration file. For example:
%files
/sbin/ypbind
%config /etc/rc.d/init.d/*
%config(noreplace) /etc/yp.conf
%doc README NEWS
Use this option to help protect local modifications. If you use %config(noreplace), the file will not overwrite an existing file that has been modified. If the file has not been modified on disk, the rpm command will overwrite the file. But, if the file has been modified on disk, the rpm command will copy the new file with an extra file-name extension of .rpmnew.
Similarly, %config(missingok) means that the file does not have to exist on disk. You can use this modifier for files or links that are created during the %post scripts but will need to be removed if the package is removed.
Another special modifier, %ghost, tells the rpm command that the file should not be included in the package. You can use this to name the needed attributes for a file that the program, when installed, will create. For example, you may want to ensure that a program’s log file has certain attributes.
From:https://docs.fedoraproject.org/ro/Fedora_Draft_Documentation/0.1/html/RPM_Guide/ch09s05s03.html
强制删除所有rpm包:
rpm -qa|awk '{print "rpm -e " $0 " --allmatches --nodeps"}'|sh
RPM包常用参数 (备忘用)
1.安装一个包
# rpm -ivh
2.升级一个包
# rpm -Uvh
3.移走一个包
# rpm -e
4.安装参数
--force 即使覆盖属于其它包的文件也强迫安装
--nodeps 如果该RPM包的安装依赖其它包,即使其它包没装,也强迫安装。
5.查询一个包是否被安装
# rpm -q < rpm package name>
6.得到被安装的包的信息
# rpm -qi < rpm package name>

放着备查
* –b 当file存在并且是块文件时返回真
* -c 当file存在并且是字符文件时返回真
* -d 当pathname存在并且是一个目录时返回真
* -e 当pathname指定的文件或目录存在时返回真
* -f 当file存在并且是正规文件时返回真
* -g 当由pathname指定的文件或目录存在并且设置了SGID位时返回为真
* -h 当file存在并且是符号链接文件时返回真,该选项在一些老系统上无效
* -k 当由pathname指定的文件或目录存在并且设置了“粘滞”位时返回真
* -p 当file存在并且是命令管道时返回为真
* -r 当由pathname指定的文件或目录存在并且可读时返回为真
* -s 当file存在文件大小大于0时返回真
* -u 当由pathname指定的文件或目录存在并且设置了SUID位时返回真
* -w 当由pathname指定的文件或目录存在并且可执行时返回真。一个目录为了它的内容被访问必然是可执行的。
* -o 当由pathname指定的文件或目录存在并且被子当前进程的有效用户ID所指定的用户拥有时返回真。
UNIX Shell 里面比较字符写法:
* -eq 等于
* -ne 不等于
* -gt 大于
* -lt 小于
* -le 小于等于
* -ge 大于等于
* -z 空串
* = 两个字符相等
* != 两个字符不等
* -n 非空串
* –b 当file存在并且是块文件时返回真
* -c 当file存在并且是字符文件时返回真
* -d 当pathname存在并且是一个目录时返回真
* -e 当pathname指定的文件或目录存在时返回真
* -f 当file存在并且是正规文件时返回真
* -g 当由pathname指定的文件或目录存在并且设置了SGID位时返回为真
* -h 当file存在并且是符号链接文件时返回真,该选项在一些老系统上无效
* -k 当由pathname指定的文件或目录存在并且设置了“粘滞”位时返回真
* -p 当file存在并且是命令管道时返回为真
* -r 当由pathname指定的文件或目录存在并且可读时返回为真
* -s 当file存在文件大小大于0时返回真
* -u 当由pathname指定的文件或目录存在并且设置了SUID位时返回真
* -w 当由pathname指定的文件或目录存在并且可执行时返回真。一个目录为了它的内容被访问必然是可执行的。
* -o 当由pathname指定的文件或目录存在并且被子当前进程的有效用户ID所指定的用户拥有时返回真。
UNIX Shell 里面比较字符写法:
* -eq 等于
* -ne 不等于
* -gt 大于
* -lt 小于
* -le 小于等于
* -ge 大于等于
* -z 空串
* = 两个字符相等
* != 两个字符不等
* -n 非空串
<?php
function change($num)
{
$num_zero_result=2;
if($num==1)
return 1;
if($num==2)
return 2;
for($i=1;$i<$num-1;$i++)
{
$num_zero_result=$num_zero_result*2;
}
return $num_zero_result;
}
echo change(1);
echo change(2);
echo change(3);
echo change(4);
echo change(5);
echo change(6);
echo change(7);
echo change(8);
echo change(9);
?>
function change($num)
{
$num_zero_result=2;
if($num==1)
return 1;
if($num==2)
return 2;
for($i=1;$i<$num-1;$i++)
{
$num_zero_result=$num_zero_result*2;
}
return $num_zero_result;
}
echo change(1);
echo change(2);
echo change(3);
echo change(4);
echo change(5);
echo change(6);
echo change(7);
echo change(8);
echo change(9);
?>
写了个api,被人调用,coresearch_get_del2.php?type=deluser&uid=1456736567 发现有人用如下方式调用:
coresearch_get_del2.php?type=deluser&uid=
为空,于是本人用isset来判断失败了,最后修改为:
if(!strlen(trim($uid)))
{
echo "trim space has no number";
exit(0);
}
最好修改为:
if(empty($uid))
{
echo "trim space find has no number,is empty?";
exit(0);
}
看看区别url:
http://www.g168.net/html/PHP_006/2007/1216/20076531760459.html
Empty函数:
一)无论是Null还是真的是空:'' 用empty都能正确判断返回1值:
---------- 调试PHP ----------
11
输出完成 (耗时 0 秒) - 正常终止
二)对连接Memcache里没有值的情况其返回为false值,用empty也能判断:
---------- 调试PHP ----------
Get key1 value: This is first value
bool(false)
bool(true)
输出完成 (耗时 0 秒) - 正常终止
总之,empty函数对真的空,Null,及bool的false都能判断正确。
网上:empty:
如果 变量 是非空或非零的值,则 empty() 返回 FALSE。换句话说,""、0、"0"、NULL、FALSE、array()、var $var、未定义; 以及没有任何属性的对象都将被认为是空的,如果 var 为空,则返回 TRUE。
来自:http://www.cnblogs.com/chengmo/archive/2010/10/18/1854258.html
coresearch_get_del2.php?type=deluser&uid=
为空,于是本人用isset来判断失败了,最后修改为:
if(!strlen(trim($uid)))
{
echo "trim space has no number";
exit(0);
}
最好修改为:
if(empty($uid))
{
echo "trim space find has no number,is empty?";
exit(0);
}
看看区别url:
http://www.g168.net/html/PHP_006/2007/1216/20076531760459.html
Empty函数:
一)无论是Null还是真的是空:'' 用empty都能正确判断返回1值:
---------- 调试PHP ----------
11
输出完成 (耗时 0 秒) - 正常终止
二)对连接Memcache里没有值的情况其返回为false值,用empty也能判断:
---------- 调试PHP ----------
Get key1 value: This is first value
bool(false)
bool(true)
输出完成 (耗时 0 秒) - 正常终止
总之,empty函数对真的空,Null,及bool的false都能判断正确。
网上:empty:
如果 变量 是非空或非零的值,则 empty() 返回 FALSE。换句话说,""、0、"0"、NULL、FALSE、array()、var $var、未定义; 以及没有任何属性的对象都将被认为是空的,如果 var 为空,则返回 TRUE。
来自:http://www.cnblogs.com/chengmo/archive/2010/10/18/1854258.html
重启:
重启二:
关机一:
关机二:
[root@localhost ~]# init 0 //关机
[root@localhost ~]# init 1 //切换到单用户模式/救援模式
[root@localhost ~]# init 2 //切换到无网络连接的多用户命令行模式
[root@localhost ~]# init 3 //切换到有网络连接的多用户命令行模式
[root@localhost ~]# init 4 //不可用
[root@localhost ~]# init 5 //切换到带图形界面的多用户模式
[root@localhost ~]# init 6 //重启
本文出自:LinuxAid.com.cn 作者: sword_martin (2002-01-30 21:03:06)
在linux下一些常用的关机/重启命令有shutdown、halt、reboot、及init,它们都
可以达到重启系统的目的,但每个命令的内部工作过程是不同的,通过本文的介绍,希
望你可以更加灵活的运用各种关机命令。
1.shutdown
shutdown命令安全地将系统关机。 有些用户会使用直接断掉电源的方式来关闭linux,
这是十分危险的。因为linux与windows不同,其后台运行着许多进程,所以强制关机可能
会导致进程的数据丢失﹐使系统处于不稳定的状态﹐甚至在有的系统中会损坏硬件设备。
而在系统关机前使用shutdown命令﹐系统管理员会通知所有登录的用户系统将要关闭。
并且login指令会被冻结﹐即新的用户不能再登录。直接关机或者延迟一定的时间才关机
都是可能的﹐还可能重启。这是由所有进程〔process〕都会收到系统所送达的信号〔signal〕
决定的。这让像vi之类的程序有时间储存目前正在编辑的文档﹐而像处理邮件〔mail〕和
新闻〔news〕的程序则可以正常地离开等等。
shutdown执行它的工作是送信号〔signal〕给init程序﹐要求它改变runlevel。
Runlevel 0被用来停机〔halt〕﹐runlevel 6是用来重新激活〔reboot〕系统﹐
而runlevel 1则是被用来让系统进入管理工作可以进行的状态﹔这是预设的﹐假定没有-h也
没有-r参数给shutdown。要想了解在停机〔halt〕或者重新开机〔reboot〕过程中做了哪些
动作﹐你可以在这个文件/etc/inittab里看到这些runlevels相关的资料。
shutdown 参数说明:
[-t] 在改变到其它runlevel之前﹐告诉init多久以后关机。
[-r] 重启计算器。
[-k] 并不真正关机﹐只是送警告信号给每位登录者〔login〕。
[-h] 关机后关闭电源〔halt〕。
[-n] 不用init﹐而是自己来关机。不鼓励使用这个选项﹐而且该选项所产生的后果往
往不总是你所预期得到的。
[-c] cancel current process取消目前正在执行的关机程序。所以这个选项当然没有
时间参数﹐但是可以输入一个用来解释的讯息﹐而这信息将会送到每位使用者。
[-f] 在重启计算器〔reboot〕时忽略fsck。
[-F] 在重启计算器〔reboot〕时强迫fsck。
[-time] 设定关机〔shutdown〕前的时间。
2.halt----最简单的关机命令
其实halt就是调用shutdown -h。halt执行时﹐杀死应用进程﹐执行sync系统调用﹐
文件系统写操作完成后就会停止内核。
参数说明:
[-n] 防止sync系统调用﹐它用在用fsck修补根分区之后﹐以阻止内核用老版本的超
级块〔superblock〕覆盖修补过的超级块。
[-w] 并不是真正的重启或关机﹐只是写wtmp〔/var/log/wtmp〕纪录。
[-d] 不写wtmp纪录〔已包含在选项[-n]中〕。
[-f] 没有调用shutdown而强制关机或重启。
[-i] 关机〔或重启〕前﹐关掉所有的网络接口。
[-p] 该选项为缺省选项。就是关机时调用poweroff。
3.reboot
reboot的工作过程差不多跟halt一样﹐不过它是引发主机重启﹐而halt是关机。它
的参数与halt相差不多。
4.init
init是所有进程的祖先﹐它的进程号始终为1﹐所以发送TERM信号给init会终止所有的
用户进程﹑守护进程等。shutdown 就是使用这种机制。init定义了8个运行级别(runlevel),
init 0为关机﹐init 1为重启。关于init可以长篇大论﹐这里就不再叙述。另外还有
telinit命令可以改变init的运行级别﹐比如﹐telinit -iS可使系统进入单用户模式﹐
并且得不到使用shutdown时的信息和等待时间。
1关机命令 shutdown
好像ubuntu的终端中默认的是当前用户的命令,只是普通用户,因此在终端器中可以使用sudo -sh 转换到管理员root用户下执行命令。
1)shutdown --help
可以查看shutdown命令如何使用,当然也可以使用man shutdown命令。
2) shutdown -h now 现在立即关机
3)shutdown -r now 现在立即重启 , 或者 init 6 //重启 init 1是单用户级别, Init6才 是重新启动。
4)shutdown -r +3 三分钟后重启
5)shutdown -h +3 "The System will shutdown after 3 minutes" 提示使用者将在三分钟后关机
6)shutdown -r 20:23 在20:23时将重启计算机
7)shutdown -r 20:23 & 可以将在20:23时重启的任务放到后台去,用户可以继续操作终端
2中断命令
1)执行完命令后(若没有转到后台),可以使用CTRL+C来中止命令
2)kill 程序编码
当命令在后台执行时系统会返回一个程序编码,例如:在使用 shutdown -r 20:23 & 系统返回系统编码:4905
我们可以使用kill 4905来中止重启命令
3ps aux | grep 程序编号
我们如果知道程序的编号,我们可以使用ps aux |grep 程序编号来查询该程序编号对应的命令是什么。
例如上面的程序编号为4905 ,我们可以使用ps aux | grep 4905 就可以查到 shutdown -r 20:23 & 的命令
halt—-最简单的关机命令
其实halt就是调用shutdown -h。halt执行时﹐杀死应用进程﹐执行sync系统调用﹐文件系统写操作完成后就会停止内核。
参数说明:
[-n] 防止sync系统调用﹐它用在用fsck修补根分区之后﹐以阻止内核用老版本的超级块〔superblock〕覆盖修补过的超级块。
[-w] 并不是真正的重启或关机﹐只是写wtmp〔/var/log/wtmp〕纪录。
[-d] 不写wtmp纪录〔已包含在选项[-n]中〕。
[-f] 没有调用shutdown而强制关机或重启。
[-i] 关机〔或重启〕前﹐关掉所有的网络接口。
[-p] 该选项为缺省选项。就是关机时调用poweroff。
init
init是所有进程的祖先﹐它的进程号始终为1﹐所以发送TERM信号给init会终止所有的用户进程﹑守护进程等。shutdown 就是使用这种机制。init定义了8个运行级别(runlevel),init 0为关机﹐init 1为重启。关于init可以长篇大论﹐这里就不再叙述。另外还有telinit命令可以改变init的运行级别﹐比如﹐telinit -iS可使系统进入单用户模式﹐并且得不到使用shutdown时的信息和等待时间。
注销系统的logout命令
Logout 注销是登陆的相对操作,登陆系统后,若要离开系统,用户只要直接下达logout命令即可:
[root@localhost root]#logout
Red Hat Linuxrelease 9(Shike)
Kernel 2.4.20.8 on an i686
Login: ← 回到登陆的画面
重启二:
关机一:
关机二:
[root@localhost ~]# init 0 //关机
[root@localhost ~]# init 1 //切换到单用户模式/救援模式
[root@localhost ~]# init 2 //切换到无网络连接的多用户命令行模式
[root@localhost ~]# init 3 //切换到有网络连接的多用户命令行模式
[root@localhost ~]# init 4 //不可用
[root@localhost ~]# init 5 //切换到带图形界面的多用户模式
[root@localhost ~]# init 6 //重启
本文出自:LinuxAid.com.cn 作者: sword_martin (2002-01-30 21:03:06)
在linux下一些常用的关机/重启命令有shutdown、halt、reboot、及init,它们都
可以达到重启系统的目的,但每个命令的内部工作过程是不同的,通过本文的介绍,希
望你可以更加灵活的运用各种关机命令。
1.shutdown
shutdown命令安全地将系统关机。 有些用户会使用直接断掉电源的方式来关闭linux,
这是十分危险的。因为linux与windows不同,其后台运行着许多进程,所以强制关机可能
会导致进程的数据丢失﹐使系统处于不稳定的状态﹐甚至在有的系统中会损坏硬件设备。
而在系统关机前使用shutdown命令﹐系统管理员会通知所有登录的用户系统将要关闭。
并且login指令会被冻结﹐即新的用户不能再登录。直接关机或者延迟一定的时间才关机
都是可能的﹐还可能重启。这是由所有进程〔process〕都会收到系统所送达的信号〔signal〕
决定的。这让像vi之类的程序有时间储存目前正在编辑的文档﹐而像处理邮件〔mail〕和
新闻〔news〕的程序则可以正常地离开等等。
shutdown执行它的工作是送信号〔signal〕给init程序﹐要求它改变runlevel。
Runlevel 0被用来停机〔halt〕﹐runlevel 6是用来重新激活〔reboot〕系统﹐
而runlevel 1则是被用来让系统进入管理工作可以进行的状态﹔这是预设的﹐假定没有-h也
没有-r参数给shutdown。要想了解在停机〔halt〕或者重新开机〔reboot〕过程中做了哪些
动作﹐你可以在这个文件/etc/inittab里看到这些runlevels相关的资料。
shutdown 参数说明:
[-t] 在改变到其它runlevel之前﹐告诉init多久以后关机。
[-r] 重启计算器。
[-k] 并不真正关机﹐只是送警告信号给每位登录者〔login〕。
[-h] 关机后关闭电源〔halt〕。
[-n] 不用init﹐而是自己来关机。不鼓励使用这个选项﹐而且该选项所产生的后果往
往不总是你所预期得到的。
[-c] cancel current process取消目前正在执行的关机程序。所以这个选项当然没有
时间参数﹐但是可以输入一个用来解释的讯息﹐而这信息将会送到每位使用者。
[-f] 在重启计算器〔reboot〕时忽略fsck。
[-F] 在重启计算器〔reboot〕时强迫fsck。
[-time] 设定关机〔shutdown〕前的时间。
2.halt----最简单的关机命令
其实halt就是调用shutdown -h。halt执行时﹐杀死应用进程﹐执行sync系统调用﹐
文件系统写操作完成后就会停止内核。
参数说明:
[-n] 防止sync系统调用﹐它用在用fsck修补根分区之后﹐以阻止内核用老版本的超
级块〔superblock〕覆盖修补过的超级块。
[-w] 并不是真正的重启或关机﹐只是写wtmp〔/var/log/wtmp〕纪录。
[-d] 不写wtmp纪录〔已包含在选项[-n]中〕。
[-f] 没有调用shutdown而强制关机或重启。
[-i] 关机〔或重启〕前﹐关掉所有的网络接口。
[-p] 该选项为缺省选项。就是关机时调用poweroff。
3.reboot
reboot的工作过程差不多跟halt一样﹐不过它是引发主机重启﹐而halt是关机。它
的参数与halt相差不多。
4.init
init是所有进程的祖先﹐它的进程号始终为1﹐所以发送TERM信号给init会终止所有的
用户进程﹑守护进程等。shutdown 就是使用这种机制。init定义了8个运行级别(runlevel),
init 0为关机﹐init 1为重启。关于init可以长篇大论﹐这里就不再叙述。另外还有
telinit命令可以改变init的运行级别﹐比如﹐telinit -iS可使系统进入单用户模式﹐
并且得不到使用shutdown时的信息和等待时间。
1关机命令 shutdown
好像ubuntu的终端中默认的是当前用户的命令,只是普通用户,因此在终端器中可以使用sudo -sh 转换到管理员root用户下执行命令。
1)shutdown --help
可以查看shutdown命令如何使用,当然也可以使用man shutdown命令。
2) shutdown -h now 现在立即关机
3)shutdown -r now 现在立即重启 , 或者 init 6 //重启 init 1是单用户级别, Init6才 是重新启动。
4)shutdown -r +3 三分钟后重启
5)shutdown -h +3 "The System will shutdown after 3 minutes" 提示使用者将在三分钟后关机
6)shutdown -r 20:23 在20:23时将重启计算机
7)shutdown -r 20:23 & 可以将在20:23时重启的任务放到后台去,用户可以继续操作终端
2中断命令
1)执行完命令后(若没有转到后台),可以使用CTRL+C来中止命令
2)kill 程序编码
当命令在后台执行时系统会返回一个程序编码,例如:在使用 shutdown -r 20:23 & 系统返回系统编码:4905
我们可以使用kill 4905来中止重启命令
3ps aux | grep 程序编号
我们如果知道程序的编号,我们可以使用ps aux |grep 程序编号来查询该程序编号对应的命令是什么。
例如上面的程序编号为4905 ,我们可以使用ps aux | grep 4905 就可以查到 shutdown -r 20:23 & 的命令
halt—-最简单的关机命令
其实halt就是调用shutdown -h。halt执行时﹐杀死应用进程﹐执行sync系统调用﹐文件系统写操作完成后就会停止内核。
参数说明:
[-n] 防止sync系统调用﹐它用在用fsck修补根分区之后﹐以阻止内核用老版本的超级块〔superblock〕覆盖修补过的超级块。
[-w] 并不是真正的重启或关机﹐只是写wtmp〔/var/log/wtmp〕纪录。
[-d] 不写wtmp纪录〔已包含在选项[-n]中〕。
[-f] 没有调用shutdown而强制关机或重启。
[-i] 关机〔或重启〕前﹐关掉所有的网络接口。
[-p] 该选项为缺省选项。就是关机时调用poweroff。
init
init是所有进程的祖先﹐它的进程号始终为1﹐所以发送TERM信号给init会终止所有的用户进程﹑守护进程等。shutdown 就是使用这种机制。init定义了8个运行级别(runlevel),init 0为关机﹐init 1为重启。关于init可以长篇大论﹐这里就不再叙述。另外还有telinit命令可以改变init的运行级别﹐比如﹐telinit -iS可使系统进入单用户模式﹐并且得不到使用shutdown时的信息和等待时间。
注销系统的logout命令
Logout 注销是登陆的相对操作,登陆系统后,若要离开系统,用户只要直接下达logout命令即可:
[root@localhost root]#logout
Red Hat Linuxrelease 9(Shike)
Kernel 2.4.20.8 on an i686
Login: ← 回到登陆的画面
由于要作项目开发,考虑到就几个人同时开发,于是想用下CVS
CVS ---Concurrent Versions system(并发版本管理系统)是一个版本控制管理系统,他是目前最为广泛使用的一个系统.大家只要曾经下载过linux的软件源代码(比如tar.gz的文件)你可以在没一个目录下看到CVS目录,那就说明他的软件是CVS进行控制的.
目前基本上流行的Linux发布版本都自带有cvs.
CVS初始化
---------------------------------
----------------------------------
环境设置:指定CVS库的路径CVSROOT
tcsh中设置
setenv CVSROOT /yourpath
bash中设置
export CVSROOT=/yourpath
初始化:
%cvs init
这时会在你的$CVSROOT目录下产生CVSROOT目录,下面是他生成的一些文件.
尽量不要去改变他.
一个项目的导入:
现在把我们的项目导入到CVS中去
%cvs import -m "your comment message" yourprojectname vendor_tag release_tag
执行后,会把当前目录下的所有文件(包括子目录)导入到/yourpath/yourprojectname目录中去
vender_tag:开发伤标记
release_tag:版本发布标记
现在你可以删去原来的源代码了.
ok,现在可以使用CVS了,找到一个合适的目录执行
%cvs checkout project_name
cvs将创建project_name目录,并将最新版本的源代码导出到相应的目录中.
CVS的基本使用
----------------------------------
----------------------------------
当你执行过cvs checkout,就不要来再次导出了,以后只要使用
%cvs update
来同步文件,如果连带子目录也要同步,就必需使用
%cvs update -d 了.
添加文件:
当你新写了一个文件后,可以使用
%cvs add filename来提交
这时其实文件并没有真正的提交,\如果要确定提交,使用下面的命令
%cvs commit -m "your comment"
删除文件:
%cvs rm filename
%cvs commit -m "why delete this file(s)"
导出发布不代CVS目录的源代码
如果系统完成了,需要发布,使用cvs export命令,不过export只是针对一个TAG或者日期导出,可以是这些命令方式:
%cvs export -r release1 project_name
%cvs export -D 20040303 project_name
%cvs export -D now project_name
对于cvs client端,如果使用linux,则已经有了,如果是windows,就使用wincvs吧.
这里要考虑到cvs的远程认证,我们使用cvs本身的pserver的认证方式
首先在服务器端建立启动文件
#cd /etc/xinted.d/
#cat cvsperver
# default: off
service cvspserver
{
disable = no
port = 2401
socket_type = stream
wait = no
#only_from = 127.0.0.1
user = apache
server = /usr/bin/cvs
passenv =/wpm-source/CVSROOT/passwd
server_args =-f --allow-root=/wpm-source pserver
log_on_failure += USERID
}
重新启动xinted
#kill -HUP xinted
然后进入你的$CVSROOT/CVSROOT目录,要建立passwd文件
这个文件的格式是
username:password:map_system_user
其中密码加密方式和apache中的加密方式一样,于是我们可以这样作:
#htpasswd -c passwd yourname
#cat passwd
yourname:sEylx9?G:apache
注意passwd文件后面的passwd是后来手工加入的.
如果你觉得这样麻烦,你可以使用cvstrac来管理.
cvstrac可以在
http://www.cvstrac.org
下载,我使用了,暂时还没有发现他的好处.
在客户端使用下面的命令来将项目导出
%cvs -d :pserver:yourname@yourip(or hostanme)#port/yourcvsroot checkout yourprojectname
这样就会在当前目录下建立yourprojectname的目录了.
现在你就可以在这个目录下做你的工作了.做完后,使用cvs基本使用中提到的命令来修改,更新和添加文件,就象在本地使用一样.
你最好设立这样的环境变量,这样下次开机就不要输入重复的命令
在/etc/profile文件中加入这样两行
CVSROOT=:pserver:yourname@cvsrootipaddress#port/cvsroot
export CVSROOT
就可以了.
使用感想:
阅读全文
CVS ---Concurrent Versions system(并发版本管理系统)是一个版本控制管理系统,他是目前最为广泛使用的一个系统.大家只要曾经下载过linux的软件源代码(比如tar.gz的文件)你可以在没一个目录下看到CVS目录,那就说明他的软件是CVS进行控制的.
目前基本上流行的Linux发布版本都自带有cvs.
CVS初始化
---------------------------------
----------------------------------
环境设置:指定CVS库的路径CVSROOT
tcsh中设置
setenv CVSROOT /yourpath
bash中设置
export CVSROOT=/yourpath
初始化:
%cvs init
这时会在你的$CVSROOT目录下产生CVSROOT目录,下面是他生成的一些文件.
尽量不要去改变他.
一个项目的导入:
现在把我们的项目导入到CVS中去
%cvs import -m "your comment message" yourprojectname vendor_tag release_tag
执行后,会把当前目录下的所有文件(包括子目录)导入到/yourpath/yourprojectname目录中去
vender_tag:开发伤标记
release_tag:版本发布标记
现在你可以删去原来的源代码了.
ok,现在可以使用CVS了,找到一个合适的目录执行
%cvs checkout project_name
cvs将创建project_name目录,并将最新版本的源代码导出到相应的目录中.
CVS的基本使用
----------------------------------
----------------------------------
当你执行过cvs checkout,就不要来再次导出了,以后只要使用
%cvs update
来同步文件,如果连带子目录也要同步,就必需使用
%cvs update -d 了.
添加文件:
当你新写了一个文件后,可以使用
%cvs add filename来提交
这时其实文件并没有真正的提交,\如果要确定提交,使用下面的命令
%cvs commit -m "your comment"
删除文件:
%cvs rm filename
%cvs commit -m "why delete this file(s)"
导出发布不代CVS目录的源代码
如果系统完成了,需要发布,使用cvs export命令,不过export只是针对一个TAG或者日期导出,可以是这些命令方式:
%cvs export -r release1 project_name
%cvs export -D 20040303 project_name
%cvs export -D now project_name
对于cvs client端,如果使用linux,则已经有了,如果是windows,就使用wincvs吧.
这里要考虑到cvs的远程认证,我们使用cvs本身的pserver的认证方式
首先在服务器端建立启动文件
#cd /etc/xinted.d/
#cat cvsperver
# default: off
service cvspserver
{
disable = no
port = 2401
socket_type = stream
wait = no
#only_from = 127.0.0.1
user = apache
server = /usr/bin/cvs
passenv =/wpm-source/CVSROOT/passwd
server_args =-f --allow-root=/wpm-source pserver
log_on_failure += USERID
}
重新启动xinted
#kill -HUP xinted
然后进入你的$CVSROOT/CVSROOT目录,要建立passwd文件
这个文件的格式是
username:password:map_system_user
其中密码加密方式和apache中的加密方式一样,于是我们可以这样作:
#htpasswd -c passwd yourname
#cat passwd
yourname:sEylx9?G:apache
注意passwd文件后面的passwd是后来手工加入的.
如果你觉得这样麻烦,你可以使用cvstrac来管理.
cvstrac可以在
http://www.cvstrac.org
下载,我使用了,暂时还没有发现他的好处.
在客户端使用下面的命令来将项目导出
%cvs -d :pserver:yourname@yourip(or hostanme)#port/yourcvsroot checkout yourprojectname
这样就会在当前目录下建立yourprojectname的目录了.
现在你就可以在这个目录下做你的工作了.做完后,使用cvs基本使用中提到的命令来修改,更新和添加文件,就象在本地使用一样.
你最好设立这样的环境变量,这样下次开机就不要输入重复的命令
在/etc/profile文件中加入这样两行
CVSROOT=:pserver:yourname@cvsrootipaddress#port/cvsroot
export CVSROOT
就可以了.
使用感想:

在许多Web编程里,字符串总是会被大量地生成和处理的。正确地使用和处理字符串,对于PHP程
序员来说也同样越来越重要了。本文从最简单的字符串定义一直引导你到高层字符串处理技巧,希望
对大家有所帮助。
一、引号定义字符串
在PHP中,通常一个字符串被定义在一对引号中,如:
'I am a string in single quotes'
"I am a string in double quotes"
PHP语法分析器是用成对的引号来判断一个字符串的。因此,所有字符串必须使用同一种单或者双
引号来定义开始和结束。例如,下面的字串定义是不合法的:
"I am not a valid string since I have unmatching quote marks'
'Me neither!"
定义字符串时,只有一种引号被视为定义符,即单引号或双引号。于是,如果一个字符串由双引
号开始,那么只有双引号被分析器解析。这样,你就可以在双引号串中包含任何其他字符,甚至单引
号。下面的引号串都是合法的:
$s = "I am a 'single quote string' inside a double quote string";
$s = 'I am a "double quote string" inside a single quote string';
当PHP遇到与串的开头相对应的引号时,便认为已经到了字符串尾部,于是:
"Why doesn't "this" work?"
阅读全文
序员来说也同样越来越重要了。本文从最简单的字符串定义一直引导你到高层字符串处理技巧,希望
对大家有所帮助。
一、引号定义字符串
在PHP中,通常一个字符串被定义在一对引号中,如:
'I am a string in single quotes'
"I am a string in double quotes"
PHP语法分析器是用成对的引号来判断一个字符串的。因此,所有字符串必须使用同一种单或者双
引号来定义开始和结束。例如,下面的字串定义是不合法的:
"I am not a valid string since I have unmatching quote marks'
'Me neither!"
定义字符串时,只有一种引号被视为定义符,即单引号或双引号。于是,如果一个字符串由双引
号开始,那么只有双引号被分析器解析。这样,你就可以在双引号串中包含任何其他字符,甚至单引
号。下面的引号串都是合法的:
$s = "I am a 'single quote string' inside a double quote string";
$s = 'I am a "double quote string" inside a single quote string';
当PHP遇到与串的开头相对应的引号时,便认为已经到了字符串尾部,于是:
"Why doesn't "this" work?"

前段时间有人问关于C++的继承与多态的问题,当时一边调试一边讲解也算是解释通了,但后来又有朋友问起此问题,便想写点这方面的东西,问题是这样的:
#include<iostream.h>
class base
{
public:
func()
{
cout<<”this is base class”<<endl;
}
};
class x: public base
{
public:
func()
{
cout<<”this is x class”<<endl;
}
};
void main()
{
base* p=new x;
p->func();
}
就是这样一个程序,得到的结果是什么呢?答案是:”this is base class”,而问题就在于这一句话:base* p=new x,程序的本意可能是要创建一个x 的对象,但为什么执行的是base的func呢?我们先来看一下new用法,new的作用在堆里为象分配内存并为这块内存调用构造函数,并且内置了长度计算,类型转换和安全检查,通用的格式是Type *p=new Type,而在程序中使用的是base* p=new x,这样就产生了第一个问题,p到底是指向base还是指向x,按照通用的格式应该指向Type,但到底是前面的Type还是后面的Type呢?于是我便把base* p=new x 改成了x* p=new base结果出错,编译器提示不能把类型base转变成x,看来当前一个Type和后一个Type的型类不一致是会发生类型转换,正好new的内置功能里带用类型转换,不难看出这里是把第二个Type转换成第一个Type,但为什么当把base转换成x时会出误错呢?这里就引出了个上向类型转换的概念,所谓上向类型转换就是取一个对象的地址,并将其作为基类的地址一处理,也就是说只能由子类向父类转换.综合上面的解释,程序中实际上是创建了一个base类型的对象,为了证明的我结论是正确的,我又作了以下调式,在base类中添加一个函数a,在x中添加了一函数b,因为x是继承base.所以如果p是x的话那么它可以调用父类的函数a,也可以调用x类的函数b,反之则只能调到base类的函数a,而不能调用x的函数b,调式发现,结果和我想像的是相符合的,也证明了以上的结论.
其实到这里只是完成了整个问题的第一步,于是继续修改程序:
我把程序改成:
#include<iostream.h>
class base
{
public:
virtual func()
{
cout<<”this is base class”<<endl;
}
};
class x: public base
{
public:
func()
{
cout<<”this is x class”<<endl;
}
};
void main()
{
base* p=new x;
p->func();
}
这种里的修改是把func改成了虚函数,再执行,结果是:”this is x class”,这个结果似乎有点出乎意料,似乎和我第一步的结论相反,但第一步是论证是比较严谨的,于是我把注意力集中到了虚函数上.要找到本质原因,还得从虚函数的现实讲起,我们来看一下虚函数是怎样实现的,
把程序改成:
#include<iostream.h>
class base
{
public:
virtual func()
{
cout<<”this is base class”<<endl;
}
};
class x: public base
{
public:
func()
{
cout<<”this is x class”<<endl;
}
};
void main()
{
x* p=new x;
p->func();
}
注意,这里主要改的是x* p=new x,建一个x对象,则由于func函数是一个虚函数,所在这里应该调用的是x的func而当func不是虚函数时,则调用base的func函数,虚函数和普通函数到底有什么区别?编译器又是怎么处理的?我们来作一个测式,写如下程序:
#include <iostream.h>
class X{
int i;
public:
a()
{
}
};
class Y{
int i;
public:
virtual a()
{
}
};
class Z{
int i;
public:
virtual a()
{
}
virtual b()
{
}
};
void main()
{
cout<<sizeof(X)<<endl;
cout<<sizeof(Y)<<endl;
cout<<sizeof(Z)<<endl;
}
这样我们可以得到三个类的大小,分别是:4,8,8类X与类Y的构构基本相同但Y的大小是X的两倍,而X与Y的不同点就是Y的a是一个虚函数,而Y与Z的大小是相同的,但Z有两个虚函数,而Y只是一个虚函数,得出这样的结果的原因是因为不带虚函数的对象的长度是单个int的长度,而带有单个虚函数的对象长度是不带虚函数的长度再加上一个指针的长度,实际是编译器在Y中插入了一个指针(VPTR),所以带一个虚函数和带两个虚函数没有区别,都只插入了一个指针,而这个指针指向一个存放函数地址的表(虚函数据表),这个表存放着具体函数。我们用函数图来画出函数的结构:
难点就在于虚函数表的内容是依据类中的虚函数声明次序,一一填入函数指针,子类会继承父类的虚函数表,当我们在改写子类时,虚函数表就受了影响:表中元素指的函数地址不再是父类的函数地址,而是子类的函数地址。所以当我们创建一个X对像的时候,编译器能知道执行的是X的func
我们再来看:base* p=new X
前面我们讲了这里是按照向上类型转换的原则把X转换成了base,而此时baser的VPTR指针会指向X的虚函数表,所以,p->func()会执行X的func函数.
#include<iostream.h>
class base
{
public:
func()
{
cout<<”this is base class”<<endl;
}
};
class x: public base
{
public:
func()
{
cout<<”this is x class”<<endl;
}
};
void main()
{
base* p=new x;
p->func();
}
就是这样一个程序,得到的结果是什么呢?答案是:”this is base class”,而问题就在于这一句话:base* p=new x,程序的本意可能是要创建一个x 的对象,但为什么执行的是base的func呢?我们先来看一下new用法,new的作用在堆里为象分配内存并为这块内存调用构造函数,并且内置了长度计算,类型转换和安全检查,通用的格式是Type *p=new Type,而在程序中使用的是base* p=new x,这样就产生了第一个问题,p到底是指向base还是指向x,按照通用的格式应该指向Type,但到底是前面的Type还是后面的Type呢?于是我便把base* p=new x 改成了x* p=new base结果出错,编译器提示不能把类型base转变成x,看来当前一个Type和后一个Type的型类不一致是会发生类型转换,正好new的内置功能里带用类型转换,不难看出这里是把第二个Type转换成第一个Type,但为什么当把base转换成x时会出误错呢?这里就引出了个上向类型转换的概念,所谓上向类型转换就是取一个对象的地址,并将其作为基类的地址一处理,也就是说只能由子类向父类转换.综合上面的解释,程序中实际上是创建了一个base类型的对象,为了证明的我结论是正确的,我又作了以下调式,在base类中添加一个函数a,在x中添加了一函数b,因为x是继承base.所以如果p是x的话那么它可以调用父类的函数a,也可以调用x类的函数b,反之则只能调到base类的函数a,而不能调用x的函数b,调式发现,结果和我想像的是相符合的,也证明了以上的结论.
其实到这里只是完成了整个问题的第一步,于是继续修改程序:
我把程序改成:
#include<iostream.h>
class base
{
public:
virtual func()
{
cout<<”this is base class”<<endl;
}
};
class x: public base
{
public:
func()
{
cout<<”this is x class”<<endl;
}
};
void main()
{
base* p=new x;
p->func();
}
这种里的修改是把func改成了虚函数,再执行,结果是:”this is x class”,这个结果似乎有点出乎意料,似乎和我第一步的结论相反,但第一步是论证是比较严谨的,于是我把注意力集中到了虚函数上.要找到本质原因,还得从虚函数的现实讲起,我们来看一下虚函数是怎样实现的,
把程序改成:
#include<iostream.h>
class base
{
public:
virtual func()
{
cout<<”this is base class”<<endl;
}
};
class x: public base
{
public:
func()
{
cout<<”this is x class”<<endl;
}
};
void main()
{
x* p=new x;
p->func();
}
注意,这里主要改的是x* p=new x,建一个x对象,则由于func函数是一个虚函数,所在这里应该调用的是x的func而当func不是虚函数时,则调用base的func函数,虚函数和普通函数到底有什么区别?编译器又是怎么处理的?我们来作一个测式,写如下程序:
#include <iostream.h>
class X{
int i;
public:
a()
{
}
};
class Y{
int i;
public:
virtual a()
{
}
};
class Z{
int i;
public:
virtual a()
{
}
virtual b()
{
}
};
void main()
{
cout<<sizeof(X)<<endl;
cout<<sizeof(Y)<<endl;
cout<<sizeof(Z)<<endl;
}
这样我们可以得到三个类的大小,分别是:4,8,8类X与类Y的构构基本相同但Y的大小是X的两倍,而X与Y的不同点就是Y的a是一个虚函数,而Y与Z的大小是相同的,但Z有两个虚函数,而Y只是一个虚函数,得出这样的结果的原因是因为不带虚函数的对象的长度是单个int的长度,而带有单个虚函数的对象长度是不带虚函数的长度再加上一个指针的长度,实际是编译器在Y中插入了一个指针(VPTR),所以带一个虚函数和带两个虚函数没有区别,都只插入了一个指针,而这个指针指向一个存放函数地址的表(虚函数据表),这个表存放着具体函数。我们用函数图来画出函数的结构:
难点就在于虚函数表的内容是依据类中的虚函数声明次序,一一填入函数指针,子类会继承父类的虚函数表,当我们在改写子类时,虚函数表就受了影响:表中元素指的函数地址不再是父类的函数地址,而是子类的函数地址。所以当我们创建一个X对像的时候,编译器能知道执行的是X的func
我们再来看:base* p=new X
前面我们讲了这里是按照向上类型转换的原则把X转换成了base,而此时baser的VPTR指针会指向X的虚函数表,所以,p->func()会执行X的func函数.