crontab -l > /home/enrnd/crontab_bak/crontab_bak`date '+%Y%m%d'`.txt
为了不引起混淆,验证码通常是大写的,因为小写的“l”很容易让输入者误以为是“1”,造成不必要的麻烦。
虽然说判断验证码时都是忽略大小写的,但用户可能不知道,他可能要按住 Shift 键去照着图片的大写来输,为了给使用者带来方便,可使用下面的代码:
<input type="text" name="code" style="text-transform:uppercase;">
利用 text-transform 就可以让用户在输入验证码时自动大写了,不论用户是否按住了 Shift 键。
虽然说判断验证码时都是忽略大小写的,但用户可能不知道,他可能要按住 Shift 键去照着图片的大写来输,为了给使用者带来方便,可使用下面的代码:
<input type="text" name="code" style="text-transform:uppercase;">
利用 text-transform 就可以让用户在输入验证码时自动大写了,不论用户是否按住了 Shift 键。
25岁分手了,26岁好似不会恋爱了,27岁……28被家里逼着相亲
阅读全文

1、安装: pkg_add -rv minicom
2、安装完成后,# rehash,然后运行# minicom 进行配置。配置和使用前最好查询一下minicom的man页,学习一下
它的键盘操作命令。注意,如果在/usr/local/etc/minicom/下没有etc目录,就要新建一个,用于保存配置文件。
3、进入minocom界面后,按Ctrl+A调出命令模式后,再按o命令,进入配置菜单。主要调整两样,一个是串口号,一个是波特率。
我的配置是:串口设置填/dev/cuad0,波特率部份填9600 8N1。
4、配置后,选择“Save setup as...”把它存为cisco。用X命令退出minicom。
5、用串行线连接电脑串口与交换机的控制口(Console)后,用# minicom 进入minicom即可。
2、安装完成后,# rehash,然后运行# minicom 进行配置。配置和使用前最好查询一下minicom的man页,学习一下
它的键盘操作命令。注意,如果在/usr/local/etc/minicom/下没有etc目录,就要新建一个,用于保存配置文件。
3、进入minocom界面后,按Ctrl+A调出命令模式后,再按o命令,进入配置菜单。主要调整两样,一个是串口号,一个是波特率。
我的配置是:串口设置填/dev/cuad0,波特率部份填9600 8N1。
4、配置后,选择“Save setup as...”把它存为cisco。用X命令退出minicom。
5、用串行线连接电脑串口与交换机的控制口(Console)后,用# minicom 进入minicom即可。
前一阵子台湾中华航空公司驾驶员王锡爵驾机飞回大陆,国民党上上下下口口声声说:王锡爵服务华航已二十年、月入新台币二十多万元、生活条件良好、婚姻家庭都美满、儿、女皆成年、孙子即将出世,不久就可含饴弄孙、安享天伦,岂有抛弃妻儿去"投匪"的道理?有人问我意见,我嗤之以鼻,答复说:"太小看人了吧!人活着,不仅仅为了面包。"
有一阵子常听人说:李敖真是不可解的人,他有名有钱有才华、有高楼大厦、有明星老婆、有八缸的凯迪拉克名牌轿车,他为什么不知足、不安分,还要惹当局、还要叛乱、革命?我每听到这种"妻财子禄"的话,我就嗤之以鼻,答复说:"太小看人吧!人活着,不仅仅为了面包。"
"人活着,不仅仅为了面包"这一观念,在人类历史上,早就很深远了。《马太福音》第四章第四节中,耶稣就引经上之言,说:"人活着,不仅仅为了面包。"(Man shall not live by bread alone)中国古代"无求生以害仁"、"生平之志,不在温饱"等观念,也都属于这一类。
这类观念再扩大引申,便是人与"物"的役使问题。《管子》中有"君子使物,不为物使"的话;《荀子》中有"君子役物,小人役于物"的话,意思都是说:"物"是身外的,有固欣然,没有也没什么。有人看了我住的六十二坪的大厦,问我说:"你年复一年住这么大的豪华大厦,一定很开心呀!"我回答道:"别忘了我年复一年住两坪大的牢房,也一样很开心呀!"这种境界无他,"君子使物"、" 君子役物"而已。
文天祥生性善于"使物"、"役物",排场极大,府第豪奢,家里甚至养歌星为他唱歌、给他打炮,可是,他一旦从容就义,虽身处漏水的土室,也不肯以" 物"易其志,虽然自己过去耽于"物"中,但一有必要,他弃"物"如敞故展。《文子》中一段话,正好描写这位文丞相,《文子》说圣人"外与物化,而内不失情。""外与物化",是形式上也跟"物"相与俯仰,随缘折腾个没完;"内不失情",是尽管如此,但自我的理想与使命却绝对"不为物使"--一旦"物"成了障,则一律"于我如浮云"处之。王弼说"圣人之情,应物而无累于物",正是指此也。
一九八三年九月九日晨
有一阵子常听人说:李敖真是不可解的人,他有名有钱有才华、有高楼大厦、有明星老婆、有八缸的凯迪拉克名牌轿车,他为什么不知足、不安分,还要惹当局、还要叛乱、革命?我每听到这种"妻财子禄"的话,我就嗤之以鼻,答复说:"太小看人吧!人活着,不仅仅为了面包。"
"人活着,不仅仅为了面包"这一观念,在人类历史上,早就很深远了。《马太福音》第四章第四节中,耶稣就引经上之言,说:"人活着,不仅仅为了面包。"(Man shall not live by bread alone)中国古代"无求生以害仁"、"生平之志,不在温饱"等观念,也都属于这一类。
这类观念再扩大引申,便是人与"物"的役使问题。《管子》中有"君子使物,不为物使"的话;《荀子》中有"君子役物,小人役于物"的话,意思都是说:"物"是身外的,有固欣然,没有也没什么。有人看了我住的六十二坪的大厦,问我说:"你年复一年住这么大的豪华大厦,一定很开心呀!"我回答道:"别忘了我年复一年住两坪大的牢房,也一样很开心呀!"这种境界无他,"君子使物"、" 君子役物"而已。
文天祥生性善于"使物"、"役物",排场极大,府第豪奢,家里甚至养歌星为他唱歌、给他打炮,可是,他一旦从容就义,虽身处漏水的土室,也不肯以" 物"易其志,虽然自己过去耽于"物"中,但一有必要,他弃"物"如敞故展。《文子》中一段话,正好描写这位文丞相,《文子》说圣人"外与物化,而内不失情。""外与物化",是形式上也跟"物"相与俯仰,随缘折腾个没完;"内不失情",是尽管如此,但自我的理想与使命却绝对"不为物使"--一旦"物"成了障,则一律"于我如浮云"处之。王弼说"圣人之情,应物而无累于物",正是指此也。
一九八三年九月九日晨
宋朝的司马光是国家的大臣,很多人进政府的时候去拜访他,他跟对方聊天的时候,常常问一个使人很难堪的问题:你家有没有钱?被问的人都很奇怪,说司马光这么了不起的国家大臣,他对我的关怀,怎么是问我有没有钱的这种小问题啊?怎么会问到这种怪问题?后来人家一打听,才知道是什么原因。司马光的标准是说,你这个人没钱,就不能维持你的生活,就不能不为五斗米折腰,你有钱以后,他才认为你有独立的人格,这个官啊你随时可以不做,为了自己的原则可以不做,为什么呢?因为我不会饿死,我有钱可以保护我的自由。所以,有没有钱可以决定一个人有没有独来独往的人格,这就是司马光的一个标准。
阅读全文

__get __set魔术引用之我见,以及常用可替代的setParam 方法。
Php/Js/Shell/Go jackxiang 2010-3-3 18:57
__get和__set类似于.net中的属性访问器,用于给类中的私有字段赋值。但注意,一般这种方式只能给一个字段赋值,当你的类中有多个字段的时候,建议使用function getProperty(){}和function setProperty(value)的形式(类似于java)。
所以上述代码你使用的方式完全错误:
class Employee
{
$name
public function __get()
{
return $name;//取得私有字段的值
}
public function __set($propValue)
{
this->$name = $propValue;//给私有字段赋值
}
}
事实上 JAVA等OOP语言中都是将属性设置为private的,其原因就是属性属于对象自身,所以不应该直接通过外界修改(会破坏对象自身的封装),之所以有魔术方法其实是为了通过某种接口来实现特定的属性修改(也就是符合某种条件才能对自身的属性进行修改),事实上对于java来说是采用的手动设置以及获取的方式设置,php中就更为简单了,提供了魔术方法来实现,另外提供__setter和__getter是魔术方法在某些设计模式中也有用到,这可能被设计为动态属性,也就是可以为对象在外部提供属性,而不需要在定义类时定义。
1.不一定是私有属性, :__get() is utilized for reading data from inaccessible members.
2.可以在__get中增加很多逻辑,有可能你用类中的一个数组类型的变量存了很多值,__get的时候,可以根据数组的key来取值,所以不一定是直接访问某个变量
3.你不设置__get函数的时候,不可访问的变量是受保护的
具体运用:
应该说 getter和setter的作用,最大的原因是为了让变量的修改和获取“可控”
在给属性赋值的时候,通过setter可以先对赋过来的值做一次合法性检查,以避免后面可能出现的错误!
在一个php框架中具体运用,我这人把它从我们的框架中抽离了出来示意一下:
下载文件
————————————————用setParam 方法实现代码片段示例———————————————————————
getParam方法:
————————————————用__set和__get方法—————————————————
Result:
---------- 调试PHP ----------
TMController Object
(
[abc] => Array
(
[weekscore] => ab
)
)
scoreController Object
(
[abc] => Array
(
[weekscore] => abc
)
)
输出完成 (耗时 0 秒) - 正常终止
所以上述代码你使用的方式完全错误:
class Employee
{
$name
public function __get()
{
return $name;//取得私有字段的值
}
public function __set($propValue)
{
this->$name = $propValue;//给私有字段赋值
}
}
事实上 JAVA等OOP语言中都是将属性设置为private的,其原因就是属性属于对象自身,所以不应该直接通过外界修改(会破坏对象自身的封装),之所以有魔术方法其实是为了通过某种接口来实现特定的属性修改(也就是符合某种条件才能对自身的属性进行修改),事实上对于java来说是采用的手动设置以及获取的方式设置,php中就更为简单了,提供了魔术方法来实现,另外提供__setter和__getter是魔术方法在某些设计模式中也有用到,这可能被设计为动态属性,也就是可以为对象在外部提供属性,而不需要在定义类时定义。
1.不一定是私有属性, :__get() is utilized for reading data from inaccessible members.
2.可以在__get中增加很多逻辑,有可能你用类中的一个数组类型的变量存了很多值,__get的时候,可以根据数组的key来取值,所以不一定是直接访问某个变量
3.你不设置__get函数的时候,不可访问的变量是受保护的
具体运用:
应该说 getter和setter的作用,最大的原因是为了让变量的修改和获取“可控”
在给属性赋值的时候,通过setter可以先对赋过来的值做一次合法性检查,以避免后面可能出现的错误!
在一个php框架中具体运用,我这人把它从我们的框架中抽离了出来示意一下:

————————————————用setParam 方法实现代码片段示例———————————————————————
getParam方法:
————————————————用__set和__get方法—————————————————
Result:
---------- 调试PHP ----------
TMController Object
(
[abc] => Array
(
[weekscore] => ab
)
)
scoreController Object
(
[abc] => Array
(
[weekscore] => abc
)
)
输出完成 (耗时 0 秒) - 正常终止
在过去10年,德鲁克武装了我们的头脑;在未来10年,稻盛和夫将充实我们的灵魂。
阅读全文

$_ENV记载了一些系统环境变量(因为牵扯到实际的操作系统,所以不可能给出$_ENV的完整列表)。
但有些朋友的$_ENV是空的,可能是原因是:
你的php.ini的variables_order值为"GPCS",也就是说系统在定义 PHP预定义变量时的顺序是GET,POST,COOKIES,SERVER,没有定义Environment(E),你可以修改php.ini文件的 variables_order值为你想要的顺序,如:"EGPCS"。这时,$_ENV的值就可以取得了
EGPCS值(EGPCS是Environment、Get、Post、Cookies、Server的缩写 -- 这是PHP中外部变量来源的全部范围)
修改一下:
root@raspberrypi:/data/htdocs/t.jackxiang.com# /usr/bin/php -r "phpinfo();"|grep php.ini
Loaded Configuration File => /etc/php5/cli/php.ini
打开这个选项:
; Default Value: "EGPCS"
; Development Value: "GPCS"
; Production Value: "GPCS";
; http://php.net/variables-order
; variables_order = "GPCS"
variables_order = "EGPCS"
PHP中的$_ENV :来自:http://blog.sina.com.cn/s/blog_a6bbf41e010169xl.html
============================================================================
PHP中的$_ENV是一个包含服务器端环境变量的数组。它是PHP中一个超级全局变量,我们可以在PHP 程序的任何地方直接访问它。
$_ENV只是被动的接受服务器端的环境变量并把它们转换为数组元素,你可以尝试直接输出它。
当你想看看一个变量中究竟有什么东西在里面时,我所知道的方式有三种:
1、var_dump($_ENV);
2、print_r($_ENV);
3、foreach($_ENV as $key=>$val){echo $key.'--------'.$val.'<br>';}
这三种方式中,第一种我觉得最方便而且输出的内容格式清晰。
由于$_ENV变量是取决于服务器的环境变量的,从不同的服务器上获取的$_ENV变量打印出的结果可能是完全不同的。所以无法像$_SERVER 那样列出完整的列表。以下是$_ENV 数组包含的比较通用的元素:
有时候,$_ENV会为空,其原因通常是php的配置文件php.ini的配置项为:variables_order = "GPCS"。要想让$_ENV的值不为空,那么variables_order的值应该加上一个大写字母“E”,即:variables_order = "EGPCS"。
上述配置表示了PHP接受的外部变量来源及顺序,EGPCS是Environment、Get、Post、Cookies、Server的缩写。如果variables_order 的配置中缺少E ,则PHP 无法接受环境变量,那么$_ENV 也就为空了。
由于开启$_ENV,即variables_order = "EGPCS"会导致一些性能损失,按php官方的说法是,在生产环境中,不推荐使用。他们更推荐使用getenv (string $varname)函数来获取Environment中的值,而这点需要在编程时就注意到。如果编程时用了$_ENV而variables_order中又没有配置为variables_order = "EGPCS",则程序运行时可能会报错。
但有些朋友的$_ENV是空的,可能是原因是:
你的php.ini的variables_order值为"GPCS",也就是说系统在定义 PHP预定义变量时的顺序是GET,POST,COOKIES,SERVER,没有定义Environment(E),你可以修改php.ini文件的 variables_order值为你想要的顺序,如:"EGPCS"。这时,$_ENV的值就可以取得了
EGPCS值(EGPCS是Environment、Get、Post、Cookies、Server的缩写 -- 这是PHP中外部变量来源的全部范围)
修改一下:
root@raspberrypi:/data/htdocs/t.jackxiang.com# /usr/bin/php -r "phpinfo();"|grep php.ini
Loaded Configuration File => /etc/php5/cli/php.ini
打开这个选项:
; Default Value: "EGPCS"
; Development Value: "GPCS"
; Production Value: "GPCS";
; http://php.net/variables-order
; variables_order = "GPCS"
variables_order = "EGPCS"
/usr/local/php/bin/php -r "phpinfo();"|grep variables_order
variables_order => EGPCS => EGPCS
variables_order => EGPCS => EGPCS
PHP中的$_ENV :来自:http://blog.sina.com.cn/s/blog_a6bbf41e010169xl.html
============================================================================
PHP中的$_ENV是一个包含服务器端环境变量的数组。它是PHP中一个超级全局变量,我们可以在PHP 程序的任何地方直接访问它。
$_ENV只是被动的接受服务器端的环境变量并把它们转换为数组元素,你可以尝试直接输出它。
当你想看看一个变量中究竟有什么东西在里面时,我所知道的方式有三种:
1、var_dump($_ENV);
2、print_r($_ENV);
3、foreach($_ENV as $key=>$val){echo $key.'--------'.$val.'<br>';}
这三种方式中,第一种我觉得最方便而且输出的内容格式清晰。
由于$_ENV变量是取决于服务器的环境变量的,从不同的服务器上获取的$_ENV变量打印出的结果可能是完全不同的。所以无法像$_SERVER 那样列出完整的列表。以下是$_ENV 数组包含的比较通用的元素:
有时候,$_ENV会为空,其原因通常是php的配置文件php.ini的配置项为:variables_order = "GPCS"。要想让$_ENV的值不为空,那么variables_order的值应该加上一个大写字母“E”,即:variables_order = "EGPCS"。
上述配置表示了PHP接受的外部变量来源及顺序,EGPCS是Environment、Get、Post、Cookies、Server的缩写。如果variables_order 的配置中缺少E ,则PHP 无法接受环境变量,那么$_ENV 也就为空了。
由于开启$_ENV,即variables_order = "EGPCS"会导致一些性能损失,按php官方的说法是,在生产环境中,不推荐使用。他们更推荐使用getenv (string $varname)函数来获取Environment中的值,而这点需要在编程时就注意到。如果编程时用了$_ENV而variables_order中又没有配置为variables_order = "EGPCS",则程序运行时可能会报错。
“宰相肚里能撑船”最早用来形容怎样的大度?
* A. 原谅小人背后暗箭
* B. 原谅妻妾偷野食
* C. 原谅冤枉自己的人
正确答案为B!
“宰相肚里能撑船”典故有二,但都与妻妾偷人有关。
其一:相传,王安石发现自己的小妾娇娘背着他与仆人偷情,虽然很生气,但是并没有当面揭穿。中秋与娇娘赏月饮酒时,吟诗道:“日出东来还转东,乌鸦不叫竹竿捅,鲜花搂着棉蚕睡,撇下干姜门外听。”娇娘听后,马上跪下答道:“日出东来转正南,你说这话整一年。大人莫见小人怪,宰相肚里能撑船。”王安石见状,马上心软了。非但没有责怪两人,还赠银两让二人成亲。事情传开后,大家都夸赞王安石宽宏大量,从此,“宰相肚里能撑船”成为千古美谈。
其二:古时候,有个年近古稀的老宰相,又娶了个名叫彩玉的小媳妇。彩玉年方二九,长得如花似玉。自从嫁给这位老宰相,虽说有享不尽的荣华富贵,可她总是闷闷不乐,暗暗埋怨父母不该把她给一个老头子。 一天,彩玉独自到后花园赏花散步,碰上了住在花园旁边的年轻帅气的家厨助理。这位赵姓家厨做得一手好吃的祖传圣旨骨酥鱼。彩玉和年轻的家厨相谈甚欢并由此一见钟情。从那,彩玉常常偷偷地到花园里同赵姓家厨相会。有一回,彩玉对赵厨说你我花园相会,好时光总让人觉得缠绵难分。我有一计,可使咱俩天天多在一起相处,赵厨问什么妙计,彩玉就如此这般地说出了自己的主意。原来,老宰相恐怕误了早朝,专门养了一只朝鸟”。这鸟天天五更头就叫,老宰相听到鸟叫,就起身上朝。彩玉让赵厨四更前就来用竹杆捅朝鸟,让它提前叫唤,等老头子一走,他俩就可团聚了。这天,老宰相听到朝鸟的叫声,连忙起身。等来到朝房门外,刚好鼓打四更。他想,这鸟怎么叫得不准了!就转身回了家发现了真相,但他并没有声张,又上朝去了。老宰相在中秋时把彩玉和赵厨叫在一起,作诗道:“中秋之夜月当空,朝鸟不叫竹杆捅,花枝落到粉团上,老姜躲在门外听。” 赵厨一听,自知露了馅,赶忙跪在桌前,说“八月中秋月儿圆,小厨知罪跪桌前,大人不把小人怪,宰相肚里能撑船。” 彩玉见事情已经挑明,也连忙跪倒在地,说中秋良霄月偏西,十八妙龄伴古稀,相爷若肯抬贵手,粉团刚好配花枝。” 老宰相听了哈哈大笑说花枝粉团既相宜,远离相府成夫妻,两情若是久长时,莫忘圣旨骨酥鱼” 彩玉和赵厨听了,连忙叩头谢恩。从此,宰相肚里能撑船这个典故和圣旨骨酥鱼漫漫在民间开始流传。
* A. 原谅小人背后暗箭
* B. 原谅妻妾偷野食
* C. 原谅冤枉自己的人
正确答案为B!
“宰相肚里能撑船”典故有二,但都与妻妾偷人有关。
其一:相传,王安石发现自己的小妾娇娘背着他与仆人偷情,虽然很生气,但是并没有当面揭穿。中秋与娇娘赏月饮酒时,吟诗道:“日出东来还转东,乌鸦不叫竹竿捅,鲜花搂着棉蚕睡,撇下干姜门外听。”娇娘听后,马上跪下答道:“日出东来转正南,你说这话整一年。大人莫见小人怪,宰相肚里能撑船。”王安石见状,马上心软了。非但没有责怪两人,还赠银两让二人成亲。事情传开后,大家都夸赞王安石宽宏大量,从此,“宰相肚里能撑船”成为千古美谈。
其二:古时候,有个年近古稀的老宰相,又娶了个名叫彩玉的小媳妇。彩玉年方二九,长得如花似玉。自从嫁给这位老宰相,虽说有享不尽的荣华富贵,可她总是闷闷不乐,暗暗埋怨父母不该把她给一个老头子。 一天,彩玉独自到后花园赏花散步,碰上了住在花园旁边的年轻帅气的家厨助理。这位赵姓家厨做得一手好吃的祖传圣旨骨酥鱼。彩玉和年轻的家厨相谈甚欢并由此一见钟情。从那,彩玉常常偷偷地到花园里同赵姓家厨相会。有一回,彩玉对赵厨说你我花园相会,好时光总让人觉得缠绵难分。我有一计,可使咱俩天天多在一起相处,赵厨问什么妙计,彩玉就如此这般地说出了自己的主意。原来,老宰相恐怕误了早朝,专门养了一只朝鸟”。这鸟天天五更头就叫,老宰相听到鸟叫,就起身上朝。彩玉让赵厨四更前就来用竹杆捅朝鸟,让它提前叫唤,等老头子一走,他俩就可团聚了。这天,老宰相听到朝鸟的叫声,连忙起身。等来到朝房门外,刚好鼓打四更。他想,这鸟怎么叫得不准了!就转身回了家发现了真相,但他并没有声张,又上朝去了。老宰相在中秋时把彩玉和赵厨叫在一起,作诗道:“中秋之夜月当空,朝鸟不叫竹杆捅,花枝落到粉团上,老姜躲在门外听。” 赵厨一听,自知露了馅,赶忙跪在桌前,说“八月中秋月儿圆,小厨知罪跪桌前,大人不把小人怪,宰相肚里能撑船。” 彩玉见事情已经挑明,也连忙跪倒在地,说中秋良霄月偏西,十八妙龄伴古稀,相爷若肯抬贵手,粉团刚好配花枝。” 老宰相听了哈哈大笑说花枝粉团既相宜,远离相府成夫妻,两情若是久长时,莫忘圣旨骨酥鱼” 彩玉和赵厨听了,连忙叩头谢恩。从此,宰相肚里能撑船这个典故和圣旨骨酥鱼漫漫在民间开始流传。
一开始在网上找资料,最多是《Linux Serial HOWTO 中譯版》,浏览地址:http://linux.cis.nctu.edu.tw/chinese/how-to/Serial-HOWTO.html。以及众多这个版本的摘选,内容是大同小异的。
后来发现,其实串口编程的实质就是多串口属性的设置。
而属性也就下面这么几个:
c_cflag Control options
c_lflag Line options
c_iflag Input options
c_oflag Output options
c_cc Control characters
c_ispeed Input baud (new interface)
c_ospeed Output baud (new interface)
关键是理解有那些属性参数可以设置以及是什么意思。
继续找资料。发现下面的经典文章,可以说基本上所有的串口编程的文章都或多或少的参考了这篇文章,《Serial Programming Guide for POSIX Operating Systems》是一定要看的,我读的是5th Edition, 3rd Revision - Updated March 11, 2003,下载地址:http://www.easysw.com/~mike/serial/index.html
当把这篇文章看完之后,基本可以解决串口的设置问题了。不过这是一个英文的版本,本人打算在暑假里把他翻译为中文版本。
关于具体的例子:
http://www.comptechdoc.org/os/linux/programming/c/linux_pgcserial.html不错,很详细,不过比较复杂。
中文的《Linux Serial HOWTO 中譯版》上面就有不少,也很值得参考。
下面的是我的程序,一个串口读取,往mysql数据库写数据的程序:
串口相关资料:
下载文件
后来发现,其实串口编程的实质就是多串口属性的设置。
而属性也就下面这么几个:
c_cflag Control options
c_lflag Line options
c_iflag Input options
c_oflag Output options
c_cc Control characters
c_ispeed Input baud (new interface)
c_ospeed Output baud (new interface)
关键是理解有那些属性参数可以设置以及是什么意思。
继续找资料。发现下面的经典文章,可以说基本上所有的串口编程的文章都或多或少的参考了这篇文章,《Serial Programming Guide for POSIX Operating Systems》是一定要看的,我读的是5th Edition, 3rd Revision - Updated March 11, 2003,下载地址:http://www.easysw.com/~mike/serial/index.html
当把这篇文章看完之后,基本可以解决串口的设置问题了。不过这是一个英文的版本,本人打算在暑假里把他翻译为中文版本。
关于具体的例子:
http://www.comptechdoc.org/os/linux/programming/c/linux_pgcserial.html不错,很详细,不过比较复杂。
中文的《Linux Serial HOWTO 中譯版》上面就有不少,也很值得参考。
下面的是我的程序,一个串口读取,往mysql数据库写数据的程序:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "mysql.h"
#define BAUDRATE B9600
#define DEVICE "/dev/ttyS0"
#define _POSIX_SOURCE 1
#define FALSE 0
#define TRUE 1
int insertdb(int d1, int d2, int d3, int d4) {
MYSQL connect;
int res, no1, no2, sd1, sd2;
char *query = "INSERT INTO mydata ( stime, sno1, sno2, sdata1, sdata2 ) VALUES ( '%s', %d, %d, %x, %x)";
char *sql, *st1;
struct tm *ptr;
time_t lt;
no1 = d1;
no2 = d2;
sd1 = d3;
sd2 = d4;
lt = time(NULL);
ptr = localtime(<);
st1 = (char *)asctime(ptr);
st1[strlen(st1) -1 ] = '\0';
sql = (char *)malloc(255*sizeof(char));
sprintf(sql, query, st1, no1, no2, sd1, sd2);
/* debug here
printf("%c : ", st1[strlen(st1)]);
printf("%s : %d :",sql, strlen(st1));
return EXIT_SUCCESS;
*/
mysql_init(&connect);
if(mysql_real_connect(&connect, "localhost", "root", "root", "mytest", 0, NULL, 0)) {
printf("connect success!\n");
res = mysql_query(&connect, sql);
if(!res) {
printf("insert success!\n");
} else {
fprintf(stderr, "insert error %d: %s\n", mysql_errno(&connect), mysql_error(&connect));
return EXIT_FAILURE;
}
mysql_close(&connect);
} else {
fprintf(stderr, "connect fail!\n");
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
int main(void) {
int fd, res_w, res_r, i, j, k;
struct termios oldtio,newtio;
char inbuf[255];
char cbuf[4];
int buf[4];
res_w = 0;
res_r = 0;
fd = open(DEVICE, O_RDWR | O_NOCTTY ); // | O_NDELAY);
if(fd < 0) {
perror(DEVICE);
exit(-1);
}
tcgetattr(fd, &oldtio);
bzero(&newtio,sizeof(struct termios));
newtio.c_cflag|= (CLOCAL | CREAD);
newtio.c_cflag|=BAUDRATE;
newtio.c_cflag&=~CSTOPB;
newtio.c_cflag&=~PARENB;
newtio.c_cflag&=~CSIZE;
newtio.c_cflag|=CS8;
newtio.c_cflag&=~CRTSCTS;
newtio.c_lflag=0;
newtio.c_oflag=0;
newtio.c_cc[VMIN]=4;
newtio.c_cc[VTIME]=0;
newtio.c_iflag&=~(IXON|IXOFF|IXANY);
cfsetispeed(&newtio, BAUDRATE);
cfsetospeed(&newtio, BAUDRATE);
tcsetattr(fd, TCSANOW, &newtio);
tcflush(fd, TCIFLUSH);
cbuf[0] = 0x00;
// cbuf[1] = 0x00;
j = 0;
for(k = 0; k < 4; k++) {
switch (j) {
case 0:
default:
cbuf[1] = 0x00;
j = 2;
break;
case 2:
cbuf[1] = 0x02;
j = 0;
break;
}
res_w = write(fd, cbuf, 2);
/* debug here
printf("cbuf : %x %x \n", cbuf[0], cbuf[1]);
printf("buf : %x : %x : %x : %x \n", inbuf[0], inbuf[1], inbuf[2], inbuf[3]);
*/
res_r = read(fd, &inbuf, 255);
if(res_r != -1) {
for(i = 0; i < res_r; i++) {
buf[i] = (int)inbuf[i];
buf[i] = buf[i] & 0xff;
// printf(" %x ", buf[i]);
}
printf("\n");
if(insertdb(buf[0], buf[1], buf[2], buf[3]))
printf("insert into db success!");
}
else {
perror("read fail");
exit(-1);
}// if end here
}// for end here
tcsetattr(fd, TCSANOW, &oldtio);
close(fd);
exit(0);
} // main end here
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "mysql.h"
#define BAUDRATE B9600
#define DEVICE "/dev/ttyS0"
#define _POSIX_SOURCE 1
#define FALSE 0
#define TRUE 1
int insertdb(int d1, int d2, int d3, int d4) {
MYSQL connect;
int res, no1, no2, sd1, sd2;
char *query = "INSERT INTO mydata ( stime, sno1, sno2, sdata1, sdata2 ) VALUES ( '%s', %d, %d, %x, %x)";
char *sql, *st1;
struct tm *ptr;
time_t lt;
no1 = d1;
no2 = d2;
sd1 = d3;
sd2 = d4;
lt = time(NULL);
ptr = localtime(<);
st1 = (char *)asctime(ptr);
st1[strlen(st1) -1 ] = '\0';
sql = (char *)malloc(255*sizeof(char));
sprintf(sql, query, st1, no1, no2, sd1, sd2);
/* debug here
printf("%c : ", st1[strlen(st1)]);
printf("%s : %d :",sql, strlen(st1));
return EXIT_SUCCESS;
*/
mysql_init(&connect);
if(mysql_real_connect(&connect, "localhost", "root", "root", "mytest", 0, NULL, 0)) {
printf("connect success!\n");
res = mysql_query(&connect, sql);
if(!res) {
printf("insert success!\n");
} else {
fprintf(stderr, "insert error %d: %s\n", mysql_errno(&connect), mysql_error(&connect));
return EXIT_FAILURE;
}
mysql_close(&connect);
} else {
fprintf(stderr, "connect fail!\n");
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
int main(void) {
int fd, res_w, res_r, i, j, k;
struct termios oldtio,newtio;
char inbuf[255];
char cbuf[4];
int buf[4];
res_w = 0;
res_r = 0;
fd = open(DEVICE, O_RDWR | O_NOCTTY ); // | O_NDELAY);
if(fd < 0) {
perror(DEVICE);
exit(-1);
}
tcgetattr(fd, &oldtio);
bzero(&newtio,sizeof(struct termios));
newtio.c_cflag|= (CLOCAL | CREAD);
newtio.c_cflag|=BAUDRATE;
newtio.c_cflag&=~CSTOPB;
newtio.c_cflag&=~PARENB;
newtio.c_cflag&=~CSIZE;
newtio.c_cflag|=CS8;
newtio.c_cflag&=~CRTSCTS;
newtio.c_lflag=0;
newtio.c_oflag=0;
newtio.c_cc[VMIN]=4;
newtio.c_cc[VTIME]=0;
newtio.c_iflag&=~(IXON|IXOFF|IXANY);
cfsetispeed(&newtio, BAUDRATE);
cfsetospeed(&newtio, BAUDRATE);
tcsetattr(fd, TCSANOW, &newtio);
tcflush(fd, TCIFLUSH);
cbuf[0] = 0x00;
// cbuf[1] = 0x00;
j = 0;
for(k = 0; k < 4; k++) {
switch (j) {
case 0:
default:
cbuf[1] = 0x00;
j = 2;
break;
case 2:
cbuf[1] = 0x02;
j = 0;
break;
}
res_w = write(fd, cbuf, 2);
/* debug here
printf("cbuf : %x %x \n", cbuf[0], cbuf[1]);
printf("buf : %x : %x : %x : %x \n", inbuf[0], inbuf[1], inbuf[2], inbuf[3]);
*/
res_r = read(fd, &inbuf, 255);
if(res_r != -1) {
for(i = 0; i < res_r; i++) {
buf[i] = (int)inbuf[i];
buf[i] = buf[i] & 0xff;
// printf(" %x ", buf[i]);
}
printf("\n");
if(insertdb(buf[0], buf[1], buf[2], buf[3]))
printf("insert into db success!");
}
else {
perror("read fail");
exit(-1);
}// if end here
}// for end here
tcsetattr(fd, TCSANOW, &oldtio);
close(fd);
exit(0);
} // main end here
串口相关资料:

PATH_SEPARATOR是一个常量,在Linux系统中是一个" : "号,Windows上是一个";"号。所以编写程序时最好用常量 PATH_SEPARATOR 代替,否则如果系统从linux移植到win系统或反过来移植会出错!
get_include_path取得当前已有的环境变量,加上前面的设置就是新的系统include
zendframework的示例index.php里有这样一句
不知道 PATH_SEPARATOR是什么,其实就是一个常量
直接echo就知道它的值了,在linux上是一个":"号,WIN上是一个";"号
set_include_path就是设置php的包含文件路径,相当是操作系统的环境变量
<?php
// Works as of PHP 4.3.0
set_include_path('/inc');
// Works in all PHP versions
ini_set('include_path', '/inc');
?>
关于set_include_path的问题,在win下,当你要include多个路径的话,你要用";"隔开,但在linux下就使用":"隔开的。
所以上面的zf的代码真是绝配.
get_include_path取得当前已有的环境变量
get_include_path取得当前已有的环境变量,加上前面的设置就是新的系统include
zendframework的示例index.php里有这样一句
set_include_path('.' . PATH_SEPARATOR . '../library/'
PATH_SEPARATOR . './application/models/'
PATH_SEPARATOR . './application/lib/'
PATH_SEPARATOR . get_include_path());
PATH_SEPARATOR . './application/models/'
PATH_SEPARATOR . './application/lib/'
PATH_SEPARATOR . get_include_path());
不知道 PATH_SEPARATOR是什么,其实就是一个常量
直接echo就知道它的值了,在linux上是一个":"号,WIN上是一个";"号
set_include_path就是设置php的包含文件路径,相当是操作系统的环境变量
<?php
// Works as of PHP 4.3.0
set_include_path('/inc');
// Works in all PHP versions
ini_set('include_path', '/inc');
?>
关于set_include_path的问题,在win下,当你要include多个路径的话,你要用";"隔开,但在linux下就使用":"隔开的。
所以上面的zf的代码真是绝配.
get_include_path取得当前已有的环境变量
背景:发现一个电信访问联通的接口很慢,于是查到是dns的问题,这时nslookup的作用就出来了。
/# nslookup -debug time.geekbang.org
第一步:
time curl "http://api.jackxiang.com/video/getUUID?client_id=100&format=json"
real 0m2.288s
user 0m0.001s
sys 0m0.001s
第二步:
tracert api.jackxiang.com
河南郑州到北京市北京市 鹏博士宽带的DNS查询很慢
估计是dns解析慢,于是直接访问IP试一试,发现很快。
nslookup api.jackxiang.com
[root@wh-appserver413 201512]# nslookup
> Set type=any
> api.jackxiang.com
Server: 115.182.119.202
Address: 115.182.119.20#53
Non-authoritative answer:
Name: api.jackxiang.com
Address: 115.182.9.212
根据DNS服务器的IP查是不是和服务器一样的是电信,发现不是(一个在河南省郑州市 联通骨干节点联通,一个在北京联通。):
您查询的IP:202.106.0.20
本站主数据:北京市北京市 联通
参考数据一:北京市 联通
网友提交的IP:北京市 联通DNS服务器
第三步:
[root@wh-appserver413 201512]# time curl -H"Host:api.jackxiang.com" "http://115.182.119.202/video/getUUID?client_id=100&format=json"
{"status":"success","data":{"uuid":"94a8a1d6-0668-429b-807c-81e12cd0ca08"}}
real 0m0.052s
user 0m0.000s
sys 0m0.003s
也就是说河南省郑州市 联通骨干节点联通到北京联通的DNS查询太慢引起的。
________________________________________________________________________
前面两行是您电脑所使用的DNS服务器名及其IP地址!
Web版本查询:http://tool.chinaz.com/nslookup/
$ nslookup
Default Server: ns.hazzptt.net.cn
Address: 202.102.224.68
查询域名解释服务器
> set type=ns
> yahoo.com
Server: ns.hazzptt.net.cn
Address: 202.102.224.68
Non-authoritative answer:
yahoo.com nameserver = NS2.DCA.yahoo.com
yahoo.com nameserver = NS5.DCX.yahoo.com
yahoo.com nameserver = NS.EUROPE.yahoo.com
yahoo.com nameserver = NS1.yahoo.com
Authoritative answers can be found from:
NS2.DCA.yahoo.com internet address = 209.143.200.34
NS5.DCX.yahoo.com internet address = 216.32.74.10
NS.EUROPE.yahoo.com internet address = 195.67.49.25
NS1.yahoo.com internet address = 204.71.200.33
查询邮件交换记录
>set type=mx
> 21cn.com
Server: ns.hazzptt.net.cn
Address: 202.102.224.68
Non-authoritative answer:
21cn.com MX preference = 10, mail exchanger = mta.21cn.com
mta.21cn.com internet address = 59.36.102.53
mta.21cn.com internet address = 59.36.102.54
mta.21cn.com internet address = 59.36.102.55
mta.21cn.com internet address = 59.36.102.56
mta.21cn.com internet address = 59.36.102.57
mta.21cn.com internet address = 59.36.102.58
mta.21cn.com internet address = 59.36.102.50
mta.21cn.com internet address = 59.36.102.51
mta.21cn.com internet address = 59.36.102.52
> gmail.com
Server: ns.hazzptt.net.cn
Address: 202.102.224.68
Non-authoritative answer:
gmail.com MX preference = 10, mail exchanger = alt1.gmail-smtp-in.l.googl.com
gmail.com MX preference = 10, mail exchanger = alt2.gmail-smtp-in.l.googl.com
gmail.com MX preference = 50, mail exchanger = gsmtp147.google.com
gmail.com MX preference = 50, mail exchanger = gsmtp183.google.com
gmail.com MX preference = 5, mail exchanger = gmail-smtp-in.l.google.com
alt2.gmail-smtp-in.l.google.com internet address = 216.239.59.27
gsmtp147.google.com internet address = 209.185.147.27
gsmtp183.google.com internet address = 64.233.183.27
gmail-smtp-in.l.google.com internet address = 209.85.143.114
gmail-smtp-in.l.google.com internet address = 209.85.143.27
alt1.gmail-smtp-in.l.google.com internet address = 64.233.185.27
alt1.gmail-smtp-in.l.google.com internet address = 64.233.185.114
>
以上例子就使用nslookup来查询yahoo.com这个zone的名字服务器,需要将类型设置为ns来执行查询,使用类型设置为mx查询你的邮件交换记录。用来帮助获得DNS数据的工具还有很多,如dig能迅速返回整个zone的名字解析数据,dnswalk可以用来帮助查询名字服务器的设置。这些工具都可以用来帮助查找DNS的设置问题。
2)查看域名对应的Dns命令:
3)修改访问域名的Dns服务器:
解释:
server dns_server_ip,表示将内定的 local DNS 换成另一部 server
/# nslookup -debug time.geekbang.org
第一步:
time curl "http://api.jackxiang.com/video/getUUID?client_id=100&format=json"
real 0m2.288s
user 0m0.001s
sys 0m0.001s
第二步:
tracert api.jackxiang.com
河南郑州到北京市北京市 鹏博士宽带的DNS查询很慢
估计是dns解析慢,于是直接访问IP试一试,发现很快。
nslookup api.jackxiang.com
[root@wh-appserver413 201512]# nslookup
> Set type=any
> api.jackxiang.com
Server: 115.182.119.202
Address: 115.182.119.20#53
Non-authoritative answer:
Name: api.jackxiang.com
Address: 115.182.9.212
根据DNS服务器的IP查是不是和服务器一样的是电信,发现不是(一个在河南省郑州市 联通骨干节点联通,一个在北京联通。):
您查询的IP:202.106.0.20
本站主数据:北京市北京市 联通
参考数据一:北京市 联通
网友提交的IP:北京市 联通DNS服务器
第三步:
[root@wh-appserver413 201512]# time curl -H"Host:api.jackxiang.com" "http://115.182.119.202/video/getUUID?client_id=100&format=json"
{"status":"success","data":{"uuid":"94a8a1d6-0668-429b-807c-81e12cd0ca08"}}
real 0m0.052s
user 0m0.000s
sys 0m0.003s
也就是说河南省郑州市 联通骨干节点联通到北京联通的DNS查询太慢引起的。
________________________________________________________________________
C:\Documents and Settings\jackxiang>nslookup xxy.qq.com
Server: gm-captiva.tencent.com
Address: 10.6.18.41
Non-authoritative answer:
Name: xxy.qq.com
Address: 119.147.78.140
Server: gm-captiva.tencent.com
Address: 10.6.18.41
Non-authoritative answer:
Name: xxy.qq.com
Address: 119.147.78.140
前面两行是您电脑所使用的DNS服务器名及其IP地址!
Web版本查询:http://tool.chinaz.com/nslookup/
$ nslookup
Default Server: ns.hazzptt.net.cn
Address: 202.102.224.68
查询域名解释服务器
> set type=ns
> yahoo.com
Server: ns.hazzptt.net.cn
Address: 202.102.224.68
Non-authoritative answer:
yahoo.com nameserver = NS2.DCA.yahoo.com
yahoo.com nameserver = NS5.DCX.yahoo.com
yahoo.com nameserver = NS.EUROPE.yahoo.com
yahoo.com nameserver = NS1.yahoo.com
Authoritative answers can be found from:
NS2.DCA.yahoo.com internet address = 209.143.200.34
NS5.DCX.yahoo.com internet address = 216.32.74.10
NS.EUROPE.yahoo.com internet address = 195.67.49.25
NS1.yahoo.com internet address = 204.71.200.33
查询邮件交换记录
>set type=mx
> 21cn.com
Server: ns.hazzptt.net.cn
Address: 202.102.224.68
Non-authoritative answer:
21cn.com MX preference = 10, mail exchanger = mta.21cn.com
mta.21cn.com internet address = 59.36.102.53
mta.21cn.com internet address = 59.36.102.54
mta.21cn.com internet address = 59.36.102.55
mta.21cn.com internet address = 59.36.102.56
mta.21cn.com internet address = 59.36.102.57
mta.21cn.com internet address = 59.36.102.58
mta.21cn.com internet address = 59.36.102.50
mta.21cn.com internet address = 59.36.102.51
mta.21cn.com internet address = 59.36.102.52
> gmail.com
Server: ns.hazzptt.net.cn
Address: 202.102.224.68
Non-authoritative answer:
gmail.com MX preference = 10, mail exchanger = alt1.gmail-smtp-in.l.googl.com
gmail.com MX preference = 10, mail exchanger = alt2.gmail-smtp-in.l.googl.com
gmail.com MX preference = 50, mail exchanger = gsmtp147.google.com
gmail.com MX preference = 50, mail exchanger = gsmtp183.google.com
gmail.com MX preference = 5, mail exchanger = gmail-smtp-in.l.google.com
alt2.gmail-smtp-in.l.google.com internet address = 216.239.59.27
gsmtp147.google.com internet address = 209.185.147.27
gsmtp183.google.com internet address = 64.233.183.27
gmail-smtp-in.l.google.com internet address = 209.85.143.114
gmail-smtp-in.l.google.com internet address = 209.85.143.27
alt1.gmail-smtp-in.l.google.com internet address = 64.233.185.27
alt1.gmail-smtp-in.l.google.com internet address = 64.233.185.114
>
以上例子就使用nslookup来查询yahoo.com这个zone的名字服务器,需要将类型设置为ns来执行查询,使用类型设置为mx查询你的邮件交换记录。用来帮助获得DNS数据的工具还有很多,如dig能迅速返回整个zone的名字解析数据,dnswalk可以用来帮助查询名字服务器的设置。这些工具都可以用来帮助查找DNS的设置问题。
2)查看域名对应的Dns命令:
3)修改访问域名的Dns服务器:
解释:
server dns_server_ip,表示将内定的 local DNS 换成另一部 server
301和302 Http状态有啥区别?
301,302 都是HTTP状态的编码,都代表着某个URL发生了转移,不同之处在于:
301 redirect: 301 代表永久性转移(Permanently Moved),
302 redirect: 302 代表暂时性转移(Temporarily Moved ),
当然 Http 状态 200 标示没有任何问题发生。
阅读全文
301,302 都是HTTP状态的编码,都代表着某个URL发生了转移,不同之处在于:
301 redirect: 301 代表永久性转移(Permanently Moved),
302 redirect: 302 代表暂时性转移(Temporarily Moved ),
当然 Http 状态 200 标示没有任何问题发生。

[实践OK]Linux下通过ssh-keygen生成公钥放~/.ssh下,使ssh不用输入密码,免密码登录, ssh-keygen的使用方法。
Unix/LinuxC技术 jackxiang 2010-3-2 11:22
用它在Alpine上生成各种级别的密钥,RSA、DSA和ECDSA三者的签名:
有些时候,我们在复制/移动文件到另一台机器时会用到scp,因为它比较安全。但如果每次
都要输入密码,就比较烦了,尤其是在script里。不过,ssh有另一种用密钥对来验证的方
式。下面写出我生成密匙对的过程,供大家参考。
关键点:
1)生成密钥的机器私钥不动,公钥给待连接的服务器。
2)公钥放到要待连接的机器上要改名为:authorized_keys。(mv id_rsa.pub authorized_keys)
3)权限得要是700:chmod -R 700 authorized_keys,在谁家就是chown 谁的权限,总之,在某人hime目录下面就只能某人读取即可,不需要其他人能读取或修改,一旦chown 后,755不必了,也是为了安全,# chmod 600 authorized_keys即可读取写入即可,记住:目录是700,里面的文件是600,也就是只能这个用户读取600,这个目录也是只能这个用户进入也就是目录得有x。
4)服务端:放谁的Home目录下在服务端执行命令时就是谁。
5)客户端:在客户端登录时如不指明用户,就是客户端的用户名,如:客户端是root用户,不指名则是root@xx.xx.xx.xx去连接。如果服务端也是放/root/.ssh/authorized_key下,刚好,如客户端不是root,是test,则直接ssh是肯定连接不上的,因为变成了:test@xx.xx.xx.xx。
6)同样,你客户client端连接时是xiangdong,但你生成密钥时是root(公钥匙放到待连接机的/home/xiangdong/.ssh/下。),此时也是对不上的,得以root环境(因为他要找当时生成密钥的私钥,你client本地换成了xiangodng,它没有了。)
7)所以,鉴于6这种情况,最好生成时的用户和待连接的用户一样(实践证明如果lvops用户设置后,如果root下执行ssh -llvops xx.xx.xx.xx 也是需要密码的,而su到lvops就能免密码登陆成功,这块ansible是可以的,因为如xiangdong的/home/.ansible.cfg自己设置了id_rsa文件路径,而root下用ssh -l这种方法并没有带上id_rsa的路径去登陆,所以还是需要密码的。private_key_file = /home/xiangdong/irdcops_private_key 前面文件来自后面拷贝:private_key_file = /home/lvops/.ssh/id_rsa ,这块儿如果是root操作注意把irdcops_private_key权限为xiangdong且能读取,否则ansible没法读取也就会需要密码或报错的问题。http://jackxiang.com/post/8967/),这样就会省去指定也好,用户名对不上,还得指定才行的这些小问题引发连接不上的问题。
第七点,也是实践证明了的,符合上面1-6点后,也就不用指明用户名了,如下:
[xiangdong@localhost .ssh]$ ssh 10.70.37.24
The authenticity of host '10.70.37.24 (10.70.37.24)' can't be established.
RSA key fingerprint is 56:94:6d:81:f3:e5:e2:8b:90:0a:93:3b:8e:7e:fd:c8.
Please type 'yes' or 'no': yes
Warning: Permanently added '10.70.37.24' (RSA) to the list of known hosts.
Last login: Thu May 5 17:27:03 2016 from 192.168.101.227
http://blog.csdn.net/kongqz/article/details/6338690
——————————————————生成步骤如下:——————————————————
第一步:生成密匙对,我用的是rsa的密钥。使用命令 "ssh-keygen -t rsa"
[user1@rh user1]$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/user1/.ssh/id_rsa):
Created directory '/home/user1/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/user1/.ssh/id_rsa.
Your public key has been saved in /home/user1/.ssh/id_rsa.pub.
The key fingerprint is:
e0:f0:3b:d3:0a:3d:da:42:01:6a:61:2f:6c:a0:c6:e7 user1@rh.test.com
[user1@rh user1]$
我的:
注意,我这儿:
这儿公用密钥:/root/.ssh2/id_rsa_2048_a.pub
私有密钥:/root/.ssh2/id_rsa_2048_a
生成的过程中提示输入密钥对保存位置,直接回车,接受默认值就行了。接着会提示输入一
个不同于你的password的密码,直接回车,让它空着。当然,也可以输入一个。(我比较懒
,不想每次都要输入密码。) 这样,密钥对就生成完了。
其中公共密钥保存在 ~/.ssh/id_rsa.pub =》 /root/.ssh2/id_rsa_2048_a.pub
私有密钥保存在 ~/.ssh/id_rsa =》/root/.ssh2/id_rsa_2048_a
然后改一下 .ssh 目录的权限,使用命令 "chmod 755 ~/.ssh" =》chmod 755 /root/.ssh2
[user1@rh user1]$ chmod 755 /root/.ssh
[user1@rh user1]$
之后把这个密钥对中的公共密钥复制到你要访问的机器上去(被以前需要密码访问的机器上),并保存为
~/.ssh/authorized_keys #My: mv id_rsa_2048_a.pub authorized_key
[user1@rh user1]$ scp ~/.ssh/id_rsa.pub rh1:/home/user1/.ssh/authorized_keys //特别注意:这个是在服务器端操作的
user1@rh1's password:
id_rsa.pub 100% 228 3.2MB/s 00:00
[user1@rh user1]$
之这样就大功告成了。之后你再用ssh scp sftp 之类的访问那台机器时,就不用输入密码
了,用在script上更是方便。
SSH服务的配置
1、配置SSH服务的运行参数,是通过修改配置文件/etc/ssh/sshd_config实现的。
2、因为SSH服务使用默认的配置已经能够很好的工作,如果仅仅提供SSH服务不需要修改。这里只介绍一
些常用的选项。
#Port 22
定义了SSH服务监听的断口号,SSH服务默认使用的端口号是22
#Proctocol 2,1
定义了SSH服务器使用SSH协议的顺序。默认识先使用SSH2协议,如果不成功则使用SSH1协议,为了安全起
见,可以设置只使用SSH2协议。
#ListenAddress 0.0.0.0
定义SSH服务器帮定的IP地址,默认绑定服务器所有可用的IP地址.
#PermitRootLogin yes
定义是否允许管理员登陆
#PermitEmptyPasswords no
定义是否允许空密码登陆.
#PasswordAuthentication no
定义是否使用口令认证方式,如果准备使用公钥认证可以设置为no
# ps aux|grep ssh
root 2649 0.0 0.0 3360 840 ? Ss 2009 0:00 /usr/local/sbin/sshd -f /etc/ssh2/sshd2_config.l
vi /etc/ssh2/sshd2_config.l
即可!
四 :
吧 id_rsa ,拷到客户端,在服务器端吧id_rsa.pub 改名为authorized_keys
cat id_rsa.pub >> authorized_keys
注意:
ssh2的配置:
#PermitRootLogin yes
定义是否允许管理员登陆
#PermitEmptyPasswords no
定义是否允许空密码登陆.
把 id_rsa ,拷到客户端,在服务器端吧id_rsa.pub 改名为authorized_keys
mv id_rsa_2048_a.pub authorized_key 这个是公钥重新命名。而客户端则是安装在自己的机器上这儿是:id_rsa_2048_a
别弄反了!
写在最后:
root
Jackxiang:/root/.ssh2 # scp ~/.ssh2/id_rsa_2048_a /root/.ssh2/authorized_keys21
scp: warning: stat: id_rsa_2048_a (src): no such file (server msg: 'syserr: No such file or directory, file: /home/admin/.ssh2/id_rsa_2048_a')
Tencent:/root/.ssh2 # whoami
root
admin:x:0:100::/home/admin:/bin/bash
Jackxiang:/root/.ssh2 # ls /home/admin
***
不是真正的root,是root这个组的,于是得拷贝到:
/home/admin/.ssh2/ 下,才行!
附送,方便一键ssh连接:
都三年前写的了,
今年2011加上个参考:http://chenlb.blogjava.net/archive/2008/07/03/212293.html
有些时候,我们在复制/移动文件到另一台机器时会用到scp,因为它比较安全。但如果每次
都要输入密码,就比较烦了,尤其是在script里。不过,ssh有另一种用密钥对来验证的方
式。下面写出我生成密匙对的过程,供大家参考。
关键点:
1)生成密钥的机器私钥不动,公钥给待连接的服务器。
2)公钥放到要待连接的机器上要改名为:authorized_keys。(mv id_rsa.pub authorized_keys)
3)权限得要是700:chmod -R 700 authorized_keys,在谁家就是chown 谁的权限,总之,在某人hime目录下面就只能某人读取即可,不需要其他人能读取或修改,一旦chown 后,755不必了,也是为了安全,# chmod 600 authorized_keys即可读取写入即可,记住:目录是700,里面的文件是600,也就是只能这个用户读取600,这个目录也是只能这个用户进入也就是目录得有x。
4)服务端:放谁的Home目录下在服务端执行命令时就是谁。
5)客户端:在客户端登录时如不指明用户,就是客户端的用户名,如:客户端是root用户,不指名则是root@xx.xx.xx.xx去连接。如果服务端也是放/root/.ssh/authorized_key下,刚好,如客户端不是root,是test,则直接ssh是肯定连接不上的,因为变成了:test@xx.xx.xx.xx。
6)同样,你客户client端连接时是xiangdong,但你生成密钥时是root(公钥匙放到待连接机的/home/xiangdong/.ssh/下。),此时也是对不上的,得以root环境(因为他要找当时生成密钥的私钥,你client本地换成了xiangodng,它没有了。)
7)所以,鉴于6这种情况,最好生成时的用户和待连接的用户一样(实践证明如果lvops用户设置后,如果root下执行ssh -llvops xx.xx.xx.xx 也是需要密码的,而su到lvops就能免密码登陆成功,这块ansible是可以的,因为如xiangdong的/home/.ansible.cfg自己设置了id_rsa文件路径,而root下用ssh -l这种方法并没有带上id_rsa的路径去登陆,所以还是需要密码的。private_key_file = /home/xiangdong/irdcops_private_key 前面文件来自后面拷贝:private_key_file = /home/lvops/.ssh/id_rsa ,这块儿如果是root操作注意把irdcops_private_key权限为xiangdong且能读取,否则ansible没法读取也就会需要密码或报错的问题。http://jackxiang.com/post/8967/),这样就会省去指定也好,用户名对不上,还得指定才行的这些小问题引发连接不上的问题。
第七点,也是实践证明了的,符合上面1-6点后,也就不用指明用户名了,如下:
[xiangdong@localhost .ssh]$ ssh 10.70.37.24
The authenticity of host '10.70.37.24 (10.70.37.24)' can't be established.
RSA key fingerprint is 56:94:6d:81:f3:e5:e2:8b:90:0a:93:3b:8e:7e:fd:c8.
Please type 'yes' or 'no': yes
Warning: Permanently added '10.70.37.24' (RSA) to the list of known hosts.
Last login: Thu May 5 17:27:03 2016 from 192.168.101.227
http://blog.csdn.net/kongqz/article/details/6338690
——————————————————生成步骤如下:——————————————————
第一步:生成密匙对,我用的是rsa的密钥。使用命令 "ssh-keygen -t rsa"
[user1@rh user1]$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/user1/.ssh/id_rsa):
Created directory '/home/user1/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/user1/.ssh/id_rsa.
Your public key has been saved in /home/user1/.ssh/id_rsa.pub.
The key fingerprint is:
e0:f0:3b:d3:0a:3d:da:42:01:6a:61:2f:6c:a0:c6:e7 user1@rh.test.com
[user1@rh user1]$
我的:
Jackxiang:/usr/local/tads/htdocs/xxy/src/view/images # ssh-keygen -t rsa
Generating 2048-bit rsa key pair
3 o.oOo.oOo.oO
Key generated.
2048-bit rsa, root@Tencent, Tue Mar 02 2010 11:26:08 +0800
Passphrase :
Again :
Key is stored with NULL passphrase.
(You can ignore the following warning if you are generating hostkeys.)
This is not recommended.
Don't do this unless you know what you're doing.
If file system protections fail (someone can access the keyfile),
or if the super-user is malicious, your key can be used without
the deciphering effort.
Private key saved to /root/.ssh2/id_rsa_2048_a
Public key saved to /root/.ssh2/id_rsa_2048_a.pub
Generating 2048-bit rsa key pair
3 o.oOo.oOo.oO
Key generated.
2048-bit rsa, root@Tencent, Tue Mar 02 2010 11:26:08 +0800
Passphrase :
Again :
Key is stored with NULL passphrase.
(You can ignore the following warning if you are generating hostkeys.)
This is not recommended.
Don't do this unless you know what you're doing.
If file system protections fail (someone can access the keyfile),
or if the super-user is malicious, your key can be used without
the deciphering effort.
Private key saved to /root/.ssh2/id_rsa_2048_a
Public key saved to /root/.ssh2/id_rsa_2048_a.pub
注意,我这儿:
这儿公用密钥:/root/.ssh2/id_rsa_2048_a.pub
私有密钥:/root/.ssh2/id_rsa_2048_a
生成的过程中提示输入密钥对保存位置,直接回车,接受默认值就行了。接着会提示输入一
个不同于你的password的密码,直接回车,让它空着。当然,也可以输入一个。(我比较懒
,不想每次都要输入密码。) 这样,密钥对就生成完了。
其中公共密钥保存在 ~/.ssh/id_rsa.pub =》 /root/.ssh2/id_rsa_2048_a.pub
私有密钥保存在 ~/.ssh/id_rsa =》/root/.ssh2/id_rsa_2048_a
然后改一下 .ssh 目录的权限,使用命令 "chmod 755 ~/.ssh" =》chmod 755 /root/.ssh2
[user1@rh user1]$ chmod 755 /root/.ssh
[user1@rh user1]$
之后把这个密钥对中的公共密钥复制到你要访问的机器上去(被以前需要密码访问的机器上),并保存为
~/.ssh/authorized_keys #My: mv id_rsa_2048_a.pub authorized_key
[user1@rh user1]$ scp ~/.ssh/id_rsa.pub rh1:/home/user1/.ssh/authorized_keys //特别注意:这个是在服务器端操作的
user1@rh1's password:
id_rsa.pub 100% 228 3.2MB/s 00:00
[user1@rh user1]$
之这样就大功告成了。之后你再用ssh scp sftp 之类的访问那台机器时,就不用输入密码
了,用在script上更是方便。
SSH服务的配置
1、配置SSH服务的运行参数,是通过修改配置文件/etc/ssh/sshd_config实现的。
2、因为SSH服务使用默认的配置已经能够很好的工作,如果仅仅提供SSH服务不需要修改。这里只介绍一
些常用的选项。
#Port 22
定义了SSH服务监听的断口号,SSH服务默认使用的端口号是22
#Proctocol 2,1
定义了SSH服务器使用SSH协议的顺序。默认识先使用SSH2协议,如果不成功则使用SSH1协议,为了安全起
见,可以设置只使用SSH2协议。
#ListenAddress 0.0.0.0
定义SSH服务器帮定的IP地址,默认绑定服务器所有可用的IP地址.
#PermitRootLogin yes
定义是否允许管理员登陆
#PermitEmptyPasswords no
定义是否允许空密码登陆.
#PasswordAuthentication no
定义是否使用口令认证方式,如果准备使用公钥认证可以设置为no
# ps aux|grep ssh
root 2649 0.0 0.0 3360 840 ? Ss 2009 0:00 /usr/local/sbin/sshd -f /etc/ssh2/sshd2_config.l
vi /etc/ssh2/sshd2_config.l
即可!
四 :
吧 id_rsa ,拷到客户端,在服务器端吧id_rsa.pub 改名为authorized_keys
cat id_rsa.pub >> authorized_keys
注意:
ssh2的配置:
#PermitRootLogin yes
定义是否允许管理员登陆
#PermitEmptyPasswords no
定义是否允许空密码登陆.
把 id_rsa ,拷到客户端,在服务器端吧id_rsa.pub 改名为authorized_keys
mv id_rsa_2048_a.pub authorized_key 这个是公钥重新命名。而客户端则是安装在自己的机器上这儿是:id_rsa_2048_a
别弄反了!
写在最后:
root
Jackxiang:/root/.ssh2 # scp ~/.ssh2/id_rsa_2048_a /root/.ssh2/authorized_keys21
scp: warning: stat: id_rsa_2048_a (src): no such file (server msg: 'syserr: No such file or directory, file: /home/admin/.ssh2/id_rsa_2048_a')
Tencent:/root/.ssh2 # whoami
root
admin:x:0:100::/home/admin:/bin/bash
Jackxiang:/root/.ssh2 # ls /home/admin
***
不是真正的root,是root这个组的,于是得拷贝到:
/home/admin/.ssh2/ 下,才行!
附送,方便一键ssh连接:
# User specific aliases and functions
alias df='df -Th'
alias l='ls -CF'
alias la='ls -A'
alias les='less -S'
alias topme='top -u `whoami`'
alias s33='ssh -Yi ~/.ssh/33 192.168.8.33'
alias s34='ssh -Yi ~/.ssh/33 192.168.8.34'
alias s35='ssh -Yi ~/.ssh/33 192.168.8.35'
alias s32='ssh -Yi ~/.ssh/33 192.168.8.32'
alias f32='sftp -oIdentityFile=~/.ssh/33 192.168.8.32'
alias s15='ssh -Yi ~/.ssh/15 192.168.8.15'
alias s16='ssh -Yi ~/.ssh/15 192.168.8.16'
alias s17='ssh -Yi ~/.ssh/15 192.168.8.17'
alias f15='sftp -oIdentityFile=~/.ssh/15 192.168.8.15'
alias df='df -Th'
alias l='ls -CF'
alias la='ls -A'
alias les='less -S'
alias topme='top -u `whoami`'
alias s33='ssh -Yi ~/.ssh/33 192.168.8.33'
alias s34='ssh -Yi ~/.ssh/33 192.168.8.34'
alias s35='ssh -Yi ~/.ssh/33 192.168.8.35'
alias s32='ssh -Yi ~/.ssh/33 192.168.8.32'
alias f32='sftp -oIdentityFile=~/.ssh/33 192.168.8.32'
alias s15='ssh -Yi ~/.ssh/15 192.168.8.15'
alias s16='ssh -Yi ~/.ssh/15 192.168.8.16'
alias s17='ssh -Yi ~/.ssh/15 192.168.8.17'
alias f15='sftp -oIdentityFile=~/.ssh/15 192.168.8.15'
都三年前写的了,
今年2011加上个参考:http://chenlb.blogjava.net/archive/2008/07/03/212293.html
php结合具体应用的yaml配置实例如下
Php/Js/Shell/Go jackxiang 2010-3-1 15:02
actInit.yaml
225: { type: 225, total: 60, daylimit: { 2010-1-28: 20, 2010-1-29: 20, 2010-1-30: 20, 2010-2-01: 20 } }
226: { type: 226, total: 60, daylimit: { 2010-1-28: 20, 2010-1-29: 20, 2010-1-30: 20, 2010-2-01: 20 } }
226: { type: 226, total: 60, daylimit: { 2010-1-28: 20, 2010-1-29: 20, 2010-1-30: 20, 2010-2-01: 20 } }
yaml_prase.php
<?php
require_once "spyc.php";
$content = @file_get_contents("./actInit.yaml");
$yaml = Spyc::YAMLLoad($content);
print_r( $yaml );
?>
require_once "spyc.php";
$content = @file_get_contents("./actInit.yaml");
$yaml = Spyc::YAMLLoad($content);
print_r( $yaml );
?>
输出array的结果如下,符合多维数组的输出要求:
Array
(
[225] => Array
(
[type] => 225
[total] => 60
[daylimit] => Array
(
[2010-1-28] => 20
[2010-1-29] => 20
[2010-1-30] => 20
[2010-2-01] => 20
)
)
[226] => Array
(
[type] => 226
[total] => 60
[daylimit] => Array
(
[2010-1-28] => 20
[2010-1-29] => 20
[2010-1-30] => 20
[2010-2-01] => 20
)
)
)