[实践OK]AWK的NR和FNR涉及高级技巧,用一行awk命令处理错开又有对应关系的两列,比用Excel更优雅,比paste更精细且相当优雅。
Php/Js/Shell/Go jack 2016-3-24 19:03
背景:我们特别是在想对两个都各带一列且没有行对齐且行数不一致的关联性的文件做关联成一行的时候,会想用自己熟悉的语言去先后打开两个文件(可能高级点的语言可以一次读取到内存,以PHP这种擅长处理字符串的语言为例,且文件要小,当然你可以对PHP占用内存作调整配置。),对文件里面的所有列全部读取到数组,再用循环对数组每行进行分割提取出关联行,再读取另外一个文件一样分离出相同的部分形成数组键,值就是一行,对第一个文件里面的关联列一个一个去第二个文件里面的数组里循环查找到查到为止,找到后,对以找到的这行的key定了,当然就对应上了,这个看起来简单,得6到7行,往往伴随着那个一行里面提取部分,也就是说需要arr=explode(sep,line),取arr某些键值和第一个文件(也可能需要类似explode操作)有关联的显示出来,你还会说,这个不难,有Excel可以实现,先对这两个文件所关联列进行排序,然后,复制粘贴在一块就OK了,感觉很简单也挺棒的,但是,假如两行的数据里面有重复行,两个文件不一样的行数,这个再像linux下的paste俩文件一样行去搞可能就会有问题了,是不是有点难搞,还得去重复啥的,其灵活性可能还是欠佳,往往需求上对重复部分只留下一个就OK的处理方式居多,Excel想做到这样引入了去重复后让两行一样多的操作,SO,有没有简单可行,优雅简洁的处理方式呢?有,那就是上面描述的可以用awk一行搞定,听说由三个数学家的名字首字母发明出来的,它优雅的使用两个类似宏的东西NR,FNR两个变量实现了上面一堆功能,对行和列处理应该相当有水平,在此,我向他们致敬。
—————————————————————————————————————————————————————————————————————————
书上说:
NR,表示awk开始执行程序后所读取的数据行数.
FNR,与NR功用类似,不同的是awk每打开一个新文件,FNR便从0重新累计.
下面看两个例子:
1,对于单个文件NR 和FNR 的 输出结果一样的 :
# awk '{print NR,$0}' file1
1 a b c d
2 a b d c
3 a c b d
#awk '{print FNR,$0}' file1
1 a b c d
2 a b d c
3 a c b d
2,但是对于多个文件 :
# awk '{print NR,$0}' file1 file2
1 a b c d
2 a b d c
3 a c b d
4 aa bb cc dd
5 aa bb dd cc
6 aa cc bb dd
# awk '{print FNR,$0}' file1 file2
1 a b c d
2 a b d c
3 a c b d
1 aa bb cc dd
2 aa bb dd cc
3 aa cc bb dd
在看一个例子关于NR和FNR的典型应用:
现在有两个文件格式如下:
#cat account
张三|000001
李四|000002
#cat cdr
000001|10
000001|20
000002|30
000002|15
想要得到的结果是将用户名,帐号和金额在同一行打印出来,如下:
张三|000001|10
张三|000001|20
李四|000002|30
李四|000002|15
执行如下代码
#awk -F \| 'NR==FNR{a[$2]=$0;next}{print a[$1]"|"$2}' account cdr
注释:
由NR=FNR为真时,判断当前读入的是第一个文件account,然后使用{a[$2]=$0;next}循环将account文件的每行记录都存入数组a,并使用$2第2个字段作为下标引用.
解释,在读取文件1时候,形成如下数组结构:
a[000001]=张三|000001
a[000002]=李四|000002
…………
由NR=FNR为假时,判断当前读入了第二个文件cdr,然后跳过{a[$2]=$0;next},对第二个文件cdr的每一行都无条件执行{print a[$1]"|"$2},此时变量$1为第二个文件的第一个字段,与读入第一个文件时,采用第一个文件第二个字段$2为数组下标相同.因此可以在此使用a[$1]引用数组。
解释,按顺序读取到第二个文件时候,文件二第一行输出数组和第二列,如下:
a[000001] | 10 => 张三|000001 | 10
第一个文件的第二列和第二个文件的第一列关联,a数组存的是第一个文件的按第二列为键值每行。
总结,NR,FNR结合next循环,在数组的key存放关键关联列信息,这个逻辑的核心就在于此,再通过这个awk列$N(N为第几列)优势,只要有关联列,就能这样去匹配出来的行可以任意列输出,相当灵活,优雅,简洁。
=====================自己在日常中的实践如下AddTime:2016-03-25===========================
两个文件里都有UUID的编号及对应的线上机器下载的UUID文件名及后缀,想变成对应的用户上传的中文名加后缀:
(中文名里有各种符号像中文的括号、竖线、空格啥的都得去掉,否则批量肯定会没法成功重命名,需求相当可恶)
windows操作系统虽然好用,但是并不适合研发人员,它的命令行(暂且只说dos, 虽然可以用vb, vbscript,
但是本人不太熟悉,写法上也不太适合做编程)实在是太弱了,想想linux下的shell,用起来还是挺方便的!
方法一:
bianhua_move_comand.txt //得把那个uuid列先单出来,当然,也可用split进行分割直接取数组1,先讲一次性解决,再讲两步来处理。
cee7b22e-f502-4fed-85a4-1db2c8c42468.mp4
1aabd2ac-2133-43d6-921d-b5bd2a34182e.mp4
./bianhua_title_uuid.txt
【新春征集】重庆两江新区《龙兴》 cee7b22e-f502-4fed-85a4-1db2c8c42468
【新春征集】重庆两江新区《伟业》 1aabd2ac-2133-43d6-921d-b5bd2a34182e
awk能够指定分隔符既可以为制表符,又可以为点,那么处理将会变得简单。可以使用正则表达式来指定多个分隔符,格式为 -F[\\t.],
直接指定两个分割符号,分别是\t,和.点,注意斜杠需要转义,awk中-F可指定两种或多种分割符号用[]括起来,awk语句及执行如下所示:
结果达到了mv移动的目的: ......
mv /path/cee7b22e-f502-4fed-85a4-1db2c8c42468.mp4 /path/newfolder/【新春征集】重庆两江新区《龙兴》.mp4
mv /path/1aabd2ac-2133-43d6-921d-b5bd2a34182e.mp4 /path/newfolder/【新春征集】重庆两江新区《伟业》.mp4
方法二:
当然,也可分两次来做,把关联的列都单独出来后,再用awk去做这个事情,总之,都需要写split分割,如下步骤:
awk -F. '{print $1"\t"$0"\t"$2}' bianhua_move_cond.txmat > bianhua_move_comand2.txt
bianhua_move_comand2.txt
经上面的awk处理后其 ./bianhua_move_comand2.txt 结构如下所示:
1aabd2ac-2133-43d6-921d-b5bd2a34182e 1aabd2ac-2133-43d6-921d-b5bd2a34182e.mp4 .mp4
1aabd2ac-2133-43d6-921d-b5bd2a34182e 1aabd2ac-2133-43d6-921d-b5bd2a34182e.mp4 .mp4
把以UUID的文件移到新的目录,并以中文对应名进行赋值,如下:
awk -F\\t 'NR==FNR{a[$1]=$0;next}NR>FNR{if($2 in a) split(a[$2],array,"\\t");print "mv /path/"array[2] " /path/newfolder/"$1array[3]}' bianhua_move_comand2.txt bianhua_title_uuid.txt
其实,去掉NR>FNR也一样可以运行,如下:
最后,还可以去掉in的数组判断,更加简化:
mv /path/cee7b22e-f502-4fed-85a4-1db2c8c42468.mp4 /path/newfolder/【新春征集】重庆两江新区《龙兴》.mp4
mv /path/1aabd2ac-2133-43d6-921d-b5bd2a34182e.mp4 /path/newfolder/【新春征集】重庆两江新区《伟业》.mp4
附录:
split(str,array,sep)
使用分隔符sep把字符串分解成数组array
if($2 in a) //假如这个$2变量在数组里面
-F \\t \| //以斜杠转义下斜杠,制表符和竖线,-F是awk指定的分割符。
假如用PHP实现的大致的流程,和上面一行解决问题起到一个比对作用:
rename.php
实践的最初素材来自:http://www.linuxidc.com/wap.aspx?nid=61174 ,及相关人的讲解,Thanks...
—————————————————————————————————————————————————————————————————————————
书上说:
NR,表示awk开始执行程序后所读取的数据行数.
FNR,与NR功用类似,不同的是awk每打开一个新文件,FNR便从0重新累计.
下面看两个例子:
1,对于单个文件NR 和FNR 的 输出结果一样的 :
# awk '{print NR,$0}' file1
1 a b c d
2 a b d c
3 a c b d
#awk '{print FNR,$0}' file1
1 a b c d
2 a b d c
3 a c b d
2,但是对于多个文件 :
# awk '{print NR,$0}' file1 file2
1 a b c d
2 a b d c
3 a c b d
4 aa bb cc dd
5 aa bb dd cc
6 aa cc bb dd
# awk '{print FNR,$0}' file1 file2
1 a b c d
2 a b d c
3 a c b d
1 aa bb cc dd
2 aa bb dd cc
3 aa cc bb dd
在看一个例子关于NR和FNR的典型应用:
现在有两个文件格式如下:
#cat account
张三|000001
李四|000002
#cat cdr
000001|10
000001|20
000002|30
000002|15
想要得到的结果是将用户名,帐号和金额在同一行打印出来,如下:
张三|000001|10
张三|000001|20
李四|000002|30
李四|000002|15
执行如下代码
#awk -F \| 'NR==FNR{a[$2]=$0;next}{print a[$1]"|"$2}' account cdr
注释:
由NR=FNR为真时,判断当前读入的是第一个文件account,然后使用{a[$2]=$0;next}循环将account文件的每行记录都存入数组a,并使用$2第2个字段作为下标引用.
解释,在读取文件1时候,形成如下数组结构:
a[000001]=张三|000001
a[000002]=李四|000002
…………
由NR=FNR为假时,判断当前读入了第二个文件cdr,然后跳过{a[$2]=$0;next},对第二个文件cdr的每一行都无条件执行{print a[$1]"|"$2},此时变量$1为第二个文件的第一个字段,与读入第一个文件时,采用第一个文件第二个字段$2为数组下标相同.因此可以在此使用a[$1]引用数组。
解释,按顺序读取到第二个文件时候,文件二第一行输出数组和第二列,如下:
a[000001] | 10 => 张三|000001 | 10
第一个文件的第二列和第二个文件的第一列关联,a数组存的是第一个文件的按第二列为键值每行。
总结,NR,FNR结合next循环,在数组的key存放关键关联列信息,这个逻辑的核心就在于此,再通过这个awk列$N(N为第几列)优势,只要有关联列,就能这样去匹配出来的行可以任意列输出,相当灵活,优雅,简洁。
=====================自己在日常中的实践如下AddTime:2016-03-25===========================
两个文件里都有UUID的编号及对应的线上机器下载的UUID文件名及后缀,想变成对应的用户上传的中文名加后缀:
(中文名里有各种符号像中文的括号、竖线、空格啥的都得去掉,否则批量肯定会没法成功重命名,需求相当可恶)
windows操作系统虽然好用,但是并不适合研发人员,它的命令行(暂且只说dos, 虽然可以用vb, vbscript,
但是本人不太熟悉,写法上也不太适合做编程)实在是太弱了,想想linux下的shell,用起来还是挺方便的!
方法一:
bianhua_move_comand.txt //得把那个uuid列先单出来,当然,也可用split进行分割直接取数组1,先讲一次性解决,再讲两步来处理。
cee7b22e-f502-4fed-85a4-1db2c8c42468.mp4
1aabd2ac-2133-43d6-921d-b5bd2a34182e.mp4
./bianhua_title_uuid.txt
【新春征集】重庆两江新区《龙兴》 cee7b22e-f502-4fed-85a4-1db2c8c42468
【新春征集】重庆两江新区《伟业》 1aabd2ac-2133-43d6-921d-b5bd2a34182e
awk能够指定分隔符既可以为制表符,又可以为点,那么处理将会变得简单。可以使用正则表达式来指定多个分隔符,格式为 -F[\\t.],
直接指定两个分割符号,分别是\t,和.点,注意斜杠需要转义,awk中-F可指定两种或多种分割符号用[]括起来,awk语句及执行如下所示:
结果达到了mv移动的目的: ......
mv /path/cee7b22e-f502-4fed-85a4-1db2c8c42468.mp4 /path/newfolder/【新春征集】重庆两江新区《龙兴》.mp4
mv /path/1aabd2ac-2133-43d6-921d-b5bd2a34182e.mp4 /path/newfolder/【新春征集】重庆两江新区《伟业》.mp4
方法二:
当然,也可分两次来做,把关联的列都单独出来后,再用awk去做这个事情,总之,都需要写split分割,如下步骤:
awk -F. '{print $1"\t"$0"\t"$2}' bianhua_move_cond.txmat > bianhua_move_comand2.txt
bianhua_move_comand2.txt
经上面的awk处理后其 ./bianhua_move_comand2.txt 结构如下所示:
1aabd2ac-2133-43d6-921d-b5bd2a34182e 1aabd2ac-2133-43d6-921d-b5bd2a34182e.mp4 .mp4
1aabd2ac-2133-43d6-921d-b5bd2a34182e 1aabd2ac-2133-43d6-921d-b5bd2a34182e.mp4 .mp4
把以UUID的文件移到新的目录,并以中文对应名进行赋值,如下:
awk -F\\t 'NR==FNR{a[$1]=$0;next}NR>FNR{if($2 in a) split(a[$2],array,"\\t");print "mv /path/"array[2] " /path/newfolder/"$1array[3]}' bianhua_move_comand2.txt bianhua_title_uuid.txt
其实,去掉NR>FNR也一样可以运行,如下:
最后,还可以去掉in的数组判断,更加简化:
mv /path/cee7b22e-f502-4fed-85a4-1db2c8c42468.mp4 /path/newfolder/【新春征集】重庆两江新区《龙兴》.mp4
mv /path/1aabd2ac-2133-43d6-921d-b5bd2a34182e.mp4 /path/newfolder/【新春征集】重庆两江新区《伟业》.mp4
附录:
split(str,array,sep)
使用分隔符sep把字符串分解成数组array
if($2 in a) //假如这个$2变量在数组里面
-F \\t \| //以斜杠转义下斜杠,制表符和竖线,-F是awk指定的分割符。
假如用PHP实现的大致的流程,和上面一行解决问题起到一个比对作用:
rename.php
实践的最初素材来自:http://www.linuxidc.com/wap.aspx?nid=61174 ,及相关人的讲解,Thanks...
SecureCRT使用之自动记录日志功能及位置在哪儿
Unix/LinuxC技术 jack 2016-3-24 09:57
首先让我们来回忆一下历史久远的手动记录日志功能:“文件”——“会话日志”,选择日志文件的存放位置并拟定文件名,点击保存。
自动记录日志功能:
1. 选择“选项”——“全局选项”,打开全局选项,在常规设置中找到“默认会话”设置项,点击右侧的“编辑默认设置”:
英文版下:选择“Options”——“Global Options”,打开全局选项,在常规设置中找到“default session”设置项,点击右侧的“edit default settings”:
2. 上一步骤操作后,打开如下图所示的界面,选择“日志文件”(英文版下选择“Log file”),如下图所示,让我们分别解释一下右侧四个红色方框部分。
http://jingyan.baidu.com/article/335530da88aa0b19cb41c3b9.html
自动记录日志功能:
1. 选择“选项”——“全局选项”,打开全局选项,在常规设置中找到“默认会话”设置项,点击右侧的“编辑默认设置”:
英文版下:选择“Options”——“Global Options”,打开全局选项,在常规设置中找到“default session”设置项,点击右侧的“edit default settings”:
2. 上一步骤操作后,打开如下图所示的界面,选择“日志文件”(英文版下选择“Log file”),如下图所示,让我们分别解释一下右侧四个红色方框部分。
http://jingyan.baidu.com/article/335530da88aa0b19cb41c3b9.html
PHP实现异步调用方法研究
Php/Js/Shell/Go jack 2016-3-18 22:20
浏览器和服务器之间是通过 HTTP 协议进行连接通讯的。这是一种基于请求和响应模型的协议。浏览器通过 URL 向服务器发起请求,Web 服务器接收到请求,执行一段程序,然后做出响应,发送相应的html代码给客户端。
这就有了一个问题,Web 服务器执行一段程序,可能几毫秒就完成,也可能几分钟都完不成。如果程序执行缓慢,用户可能没有耐心等下去,就关闭浏览器了。
而有的时候,我们更本不关心这些耗时的脚本的返回结果,但却还要等他执行完返回,才能继续下一步。
那么有没有什么办法,只是简单的触发调用这些耗时的脚本然后就继续下一步,让这些耗时的脚本在服务端慢慢执行?
经过试验,总结出来几种方法,和大家share:
1. 最简单的办法,就是在返回给客户端的HTML代码中,嵌入AJAX调用,或者,嵌入一个img标签,src指向要执行的耗时脚本。
这种方法最简单,也最快。服务器端不用做任何的调用。
但是缺点是,一般来说Ajax都应该在onLoad以后触发,也就是说,用户点开页面后,就关闭,那就不会触发我们的后台脚本了。
而使用img标签的话,这种方式不能称为严格意义上的异步执行。用户浏览器会长时间等待php脚本的执行完成,也就是用户浏览器的状态栏一直显示还在load。
当然,还可以使用其他的类似原理的方法,比如script标签等等。
2. popen()
resource popen ( string command, string mode );
//打开一个指向进程的管道,该进程由派生给定的 command 命令执行而产生。打开一个指向进程的管道,该进程由派生给定的 command 命令执行而产生。
所以可以通过调用它,但忽略它的输出。
pclose(popen("/home/xinchen/backend.php &"
这个方法避免了第一个方法的缺点,并且也很快。但是问题是,这种方法不能通过HTTP协议请求另外的一个WebService,只能执行本地的脚本文件。并且只能单向打开,无法穿大量参数给被调用脚本。
并且如果,访问量很高的时候,会产生大量的进程。如果使用到了外部资源,还要自己考虑竞争。
3. 使用CURL
这个方法,设置CUROPT_TIMEOUT为1(最小为1,郁闷)。也就是说,客户端至少必须等待1秒钟。
$ch = curl_init(); $curl_opt = array(CURLOPT_URL, 'http://www.example.com/backend.php', CURLOPT_RETURNTRANSFER, 1, CURLOPT_TIMEOUT, 1,); curl_setopt_array($ch, $curl_opt); curl_exec($ch); curl_close($ch);
4. 使用fsockopen
这个方法应该是最完美的,但是缺点是,你需要自己拼出HTTP的header部分。
$fp = fsockopen("www.example.com", 80, $errno, $errstr, 30); if (!$fp) { echo "$errstr ($errno)<br />\n"; } else { $out = "GET /backend.php / HTTP/1.1\r\n"; $out .= "Host: www.example.com\r\n"; $out .= "Connection: Close\r\n\r\n"; fwrite($fp, $out); /*忽略执行结果 while (!feof($fp)) { echo fgets($fp, 128); }*/ fclose($fp); }
所以,总体来看,最好用,最简单的还是第一种方法。
最完美的应该是最后一种,但是比较复杂
如果有更好的办法,欢迎交流。
来自:http://www.laruence.com/2008/04/14/318.html
这就有了一个问题,Web 服务器执行一段程序,可能几毫秒就完成,也可能几分钟都完不成。如果程序执行缓慢,用户可能没有耐心等下去,就关闭浏览器了。
而有的时候,我们更本不关心这些耗时的脚本的返回结果,但却还要等他执行完返回,才能继续下一步。
那么有没有什么办法,只是简单的触发调用这些耗时的脚本然后就继续下一步,让这些耗时的脚本在服务端慢慢执行?
经过试验,总结出来几种方法,和大家share:
1. 最简单的办法,就是在返回给客户端的HTML代码中,嵌入AJAX调用,或者,嵌入一个img标签,src指向要执行的耗时脚本。
这种方法最简单,也最快。服务器端不用做任何的调用。
但是缺点是,一般来说Ajax都应该在onLoad以后触发,也就是说,用户点开页面后,就关闭,那就不会触发我们的后台脚本了。
而使用img标签的话,这种方式不能称为严格意义上的异步执行。用户浏览器会长时间等待php脚本的执行完成,也就是用户浏览器的状态栏一直显示还在load。
当然,还可以使用其他的类似原理的方法,比如script标签等等。
2. popen()
resource popen ( string command, string mode );
//打开一个指向进程的管道,该进程由派生给定的 command 命令执行而产生。打开一个指向进程的管道,该进程由派生给定的 command 命令执行而产生。
所以可以通过调用它,但忽略它的输出。
pclose(popen("/home/xinchen/backend.php &"
这个方法避免了第一个方法的缺点,并且也很快。但是问题是,这种方法不能通过HTTP协议请求另外的一个WebService,只能执行本地的脚本文件。并且只能单向打开,无法穿大量参数给被调用脚本。
并且如果,访问量很高的时候,会产生大量的进程。如果使用到了外部资源,还要自己考虑竞争。
3. 使用CURL
这个方法,设置CUROPT_TIMEOUT为1(最小为1,郁闷)。也就是说,客户端至少必须等待1秒钟。
$ch = curl_init(); $curl_opt = array(CURLOPT_URL, 'http://www.example.com/backend.php', CURLOPT_RETURNTRANSFER, 1, CURLOPT_TIMEOUT, 1,); curl_setopt_array($ch, $curl_opt); curl_exec($ch); curl_close($ch);
4. 使用fsockopen
这个方法应该是最完美的,但是缺点是,你需要自己拼出HTTP的header部分。
$fp = fsockopen("www.example.com", 80, $errno, $errstr, 30); if (!$fp) { echo "$errstr ($errno)<br />\n"; } else { $out = "GET /backend.php / HTTP/1.1\r\n"; $out .= "Host: www.example.com\r\n"; $out .= "Connection: Close\r\n\r\n"; fwrite($fp, $out); /*忽略执行结果 while (!feof($fp)) { echo fgets($fp, 128); }*/ fclose($fp); }
所以,总体来看,最好用,最简单的还是第一种方法。
最完美的应该是最后一种,但是比较复杂
如果有更好的办法,欢迎交流。
来自:http://www.laruence.com/2008/04/14/318.html
[运维用到]PHP的with-config-file-path 这个是用来指定目录,不是指定文件,PHP扩展的ini配置文件目录指定。
Php/Js/Shell/Go jack 2016-3-18 16:01
背景:运行指定扩展配置文件extension.ini的扫描目录,这样结构化有利于运维进行模块添加,也是后来我运维时看到并实践的文章,参考文章,http://jackxiang.com/post/8613/。
参数 --prefix=/usr/local/php --with-config-file-scan-dir=/usr/local/php/etc/
一定要设置正确,多个PHP版本须编译安装在不同路径!!!后面编译后无法修改此项:
Set the path in which to look for php.ini [PREFIX/lib]
--with-config-file-scan-dir=PATH
php.ini的扩展目录,php -c /usr/local/php/etc/php-workerman.ini --ini=/usr/local/php/etc/php-workerman.d --help|grep scan 编译完php二进制后并没有提供参数指定。
作者:风吹我已散博客
链接:https://www.jianshu.com/p/f13402d5217e
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
PHP7在和PHP6一块时注意这个参数,下面就是编译时给指向了PHP5的目录了,出现运行报错,如下:
/usr/local/php7/bin/php start.php
PHP Warning: PHP Startup: Unable to load dynamic library 'redis.so' (tried: /usr/local/php/ext/redis.so (/usr/local/php/ext/redis.so: Undefined symbol "zval_used_for_init"), /usr/local/php/ext/redis.so.so (Cannot open "/usr/local/php/ext/redis.so.so")) in Unknown on line 0
Usage: php yourfile <command> [mode]
还原编译时的命令,如下:
/usr/local/php7/bin/php -i|grep configure 编译参数:
--with-config-file-scan-dir=/usr/local/php7/etc/php.d
个性php.ini里面的参数:
extension_dir => /usr/local/php/ext/ => /usr/local/php/ext/ #这一行没有写,所以就找到/usr/local/php/ext上去了,得写成:
extension_dir => /usr/local/php7/ext/ => /usr/local/php7/ext/
/bin/sed -i 's#; extension_dir = \"\.\/\"#extension_dir = "/usr/local/php/ext/"#' %{buildroot}/%{_prefix}/etc/php.ini
#sed -i "" 's#; extension_dir = \"\.\/\"#extension_dir = "/usr/local/php7/ext/"#' /usr/local/php7/etc/php.ini
737 extension_dir = "/usr/local/php7/ext/"
738 ; On windows:
739 ; extension_dir = "ext"
/usr/local/php/etc/php.d/redis.ini
php -m|grep redis
redis
是因为有:
--with-config-file-scan-dir=/usr/local/php/etc/php.d \
--with-config-file-scan-dir是搜索下面的ini文件和php.ini一起使用,好处就是扩展的那些extension="xx.so"可以放里面,每个扩展一个ini文件,可以方便的用自动化脚本或者部署脚本来搞,看起来模块化了
'—with-config-file-path=/data/software/php-5.6.15/lib/php.ini
open("/data/software/php-5.6.15/bin/php-cli.ini", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/data/software/php-5.6.15/lib/php.ini/php-cli.ini", O_RDONLY) = -1 ENOTDIR (Not a directory)
open("/data/software/php-5.6.15/bin/php.ini", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/data/software/php-5.6.15/lib/php.ini/php.ini", O_RDONLY) = -1 ENOTDIR (Not a directory)
求问这是bug么?
--with-config-file-path=PATH
--with-config-file-scan-dir=PATH
—with-config-file-path 这个是用来指定目录,不是指定文件。
scan这个干嘛的?还能指定php去这个配置目录扫描?
http://php.net/manual/zh/function.php-ini-scanned-files.php
php.conf.d/*.ini
应该一个是cli,一个是运行服务的吧?
不是吧 应该是搜索这个目录下的 *.ini 文件吧
scan是扩展配置文件目录
cli sapi默认都是编译时指定的位置,也可以手动指定
嗯,--with-config-file-scan-dir是搜索下面的ini文件和php.ini一起使用,好处就是扩展的那些extension="xx.so"可以放里面,每个扩展一个ini文件,可以方便的用自动化脚本或者部署脚本来搞,看起来模块化了
关于opcache想编译成静态所谓提高效率:
PHP 5.5.0 及后续版本,
OPcache 只能编译为共享扩展。
—————————————————
理论上性能好点儿,高并发可能瓶颈不在这儿,所以不明显。
静态这个是迷信 嘿嘿,嗯 所以我说这是我自己的迷信 嘿嘿。
参数 --prefix=/usr/local/php --with-config-file-scan-dir=/usr/local/php/etc/
一定要设置正确,多个PHP版本须编译安装在不同路径!!!后面编译后无法修改此项:
Set the path in which to look for php.ini [PREFIX/lib]
--with-config-file-scan-dir=PATH
php.ini的扩展目录,php -c /usr/local/php/etc/php-workerman.ini --ini=/usr/local/php/etc/php-workerman.d --help|grep scan 编译完php二进制后并没有提供参数指定。
作者:风吹我已散博客
链接:https://www.jianshu.com/p/f13402d5217e
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
PHP7在和PHP6一块时注意这个参数,下面就是编译时给指向了PHP5的目录了,出现运行报错,如下:
/usr/local/php7/bin/php start.php
PHP Warning: PHP Startup: Unable to load dynamic library 'redis.so' (tried: /usr/local/php/ext/redis.so (/usr/local/php/ext/redis.so: Undefined symbol "zval_used_for_init"), /usr/local/php/ext/redis.so.so (Cannot open "/usr/local/php/ext/redis.so.so")) in Unknown on line 0
Usage: php yourfile <command> [mode]
还原编译时的命令,如下:
/usr/local/php7/bin/php -i|grep configure 编译参数:
--with-config-file-scan-dir=/usr/local/php7/etc/php.d
个性php.ini里面的参数:
extension_dir => /usr/local/php/ext/ => /usr/local/php/ext/ #这一行没有写,所以就找到/usr/local/php/ext上去了,得写成:
extension_dir => /usr/local/php7/ext/ => /usr/local/php7/ext/
/bin/sed -i 's#; extension_dir = \"\.\/\"#extension_dir = "/usr/local/php/ext/"#' %{buildroot}/%{_prefix}/etc/php.ini
#sed -i "" 's#; extension_dir = \"\.\/\"#extension_dir = "/usr/local/php7/ext/"#' /usr/local/php7/etc/php.ini
737 extension_dir = "/usr/local/php7/ext/"
738 ; On windows:
739 ; extension_dir = "ext"
/usr/local/php/etc/php.d/redis.ini
php -m|grep redis
redis
是因为有:
--with-config-file-scan-dir=/usr/local/php/etc/php.d \
--with-config-file-scan-dir是搜索下面的ini文件和php.ini一起使用,好处就是扩展的那些extension="xx.so"可以放里面,每个扩展一个ini文件,可以方便的用自动化脚本或者部署脚本来搞,看起来模块化了
'—with-config-file-path=/data/software/php-5.6.15/lib/php.ini
open("/data/software/php-5.6.15/bin/php-cli.ini", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/data/software/php-5.6.15/lib/php.ini/php-cli.ini", O_RDONLY) = -1 ENOTDIR (Not a directory)
open("/data/software/php-5.6.15/bin/php.ini", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/data/software/php-5.6.15/lib/php.ini/php.ini", O_RDONLY) = -1 ENOTDIR (Not a directory)
求问这是bug么?
--with-config-file-path=PATH
--with-config-file-scan-dir=PATH
—with-config-file-path 这个是用来指定目录,不是指定文件。
scan这个干嘛的?还能指定php去这个配置目录扫描?
http://php.net/manual/zh/function.php-ini-scanned-files.php
php.conf.d/*.ini
应该一个是cli,一个是运行服务的吧?
不是吧 应该是搜索这个目录下的 *.ini 文件吧
scan是扩展配置文件目录
cli sapi默认都是编译时指定的位置,也可以手动指定
嗯,--with-config-file-scan-dir是搜索下面的ini文件和php.ini一起使用,好处就是扩展的那些extension="xx.so"可以放里面,每个扩展一个ini文件,可以方便的用自动化脚本或者部署脚本来搞,看起来模块化了
关于opcache想编译成静态所谓提高效率:
PHP 5.5.0 及后续版本,
OPcache 只能编译为共享扩展。
—————————————————
理论上性能好点儿,高并发可能瓶颈不在这儿,所以不明显。
静态这个是迷信 嘿嘿,嗯 所以我说这是我自己的迷信 嘿嘿。
[实践OK]MACBOOK还不知道怎么样显示桌面,macbook打开文件不用enter键显示桌面修改为option+D显示桌面的步骤。
Unix/LinuxC技术 jack 2016-3-18 00:01
一、显示桌面由F11修改为option+D的步骤如下所示:
F11相当于windows中的“显示桌面”:
fn + F11 显示桌面。或用手指在触摸板上伸开也成。
F11修改为:option+d,如下所示:
1、打开“系统偏好设置”
2、找到“键盘”并打开
3、在顶部,我们选择“快捷键”按钮
4、然后在页面的左侧我们可以看到“mission control”,中文显示:调度中心。
5、点击之后就可以看到右边的“显示桌面”勾选即可,然后可在后面设置快捷键由F11修改为:option+d。
备注:为何不用command+d呢?因为在chrome中command+d是收藏夹,会导致冲突,在用chrome时无法打开桌面。
二、
macbook打开文件不用enter键:
command+down方向键下,就可以了
enter键对着文件怼就是逼迫文件改名字~
F11相当于windows中的“显示桌面”:
fn + F11 显示桌面。或用手指在触摸板上伸开也成。
F11修改为:option+d,如下所示:
1、打开“系统偏好设置”
2、找到“键盘”并打开
3、在顶部,我们选择“快捷键”按钮
4、然后在页面的左侧我们可以看到“mission control”,中文显示:调度中心。
5、点击之后就可以看到右边的“显示桌面”勾选即可,然后可在后面设置快捷键由F11修改为:option+d。
备注:为何不用command+d呢?因为在chrome中command+d是收藏夹,会导致冲突,在用chrome时无法打开桌面。
二、
macbook打开文件不用enter键:
command+down方向键下,就可以了
enter键对着文件怼就是逼迫文件改名字~
fn+left
command+上光标键
command+上光标键
[实践OK]linux/FreeBSD/macbook 中文乱码以及tree指令的用法,查看目录结构着色和用tree看目录时显示颜色的参数 -C,CentOS下的Tree命令显示文件绝对路径tree -pf ~+|grep -v "[d"
Unix/LinuxC技术 jack 2016-3-17 18:01
macbook下的tree加上中文显示不乱码加-N :tree -N -L 2 .
-N Print non-printable characters as is instead of as escaped octal numbers.
打印不可打印的字符,而不是AS ESCAPATED八进制数字。
背景:有时查看目录结构,这个tree非常有用,yum -y install tree安装就能使用。
tree -L 2 -ugpshC
parameter explain:
-u Print the username, or UID # if no username is available, of the file.
-g Print the group name, or GID # if no group name is available, of the file.
-h option rounds to the nearest whole number unlike the ls implementation of -h which
rounds up always.
-f Print the full path prefix for each file.
-p Print the protections for each file.
tree -f ~+ #只显示目录和文件的绝对路径,注意加上这个: ~+。
tree -pf ~+ #显示目录和文件的绝对路径以及Chmod的权限,注意加上这个: ~+。
tree -pugf ~+ #显示目录和文件的绝对路径以及Chmod的权限,注意加上这个: ~+,u用户,g群组。
==============================================================
FreebsD: Have you tried installing tree with: pkg install tree ,cd /usr/ports/sysutils/tree make install
来自:https://www.reddit.com/r/freebsd/comments/4kxyx1/newbie_having_trouble_using_tree_command/
相关参数说明及常用参数说明:
要想目录和文件有颜色,或是用Tree看有颜色,得用那个SecureCRT做下配置:
Session Options->Terminal->Emulation->Terminal [Linux/Xterm] [V]ANSI Color @老武用的是Linux可以,我用的是Xterm也行,颜色可调一下即可。
常常加 -C,表示颜色,-L表示层级。 如:tree -C -L 2。
-C Turn colorization on always.
阅读全文
-N Print non-printable characters as is instead of as escaped octal numbers.
打印不可打印的字符,而不是AS ESCAPATED八进制数字。
背景:有时查看目录结构,这个tree非常有用,yum -y install tree安装就能使用。
tree -L 2 -ugpshC
parameter explain:
-u Print the username, or UID # if no username is available, of the file.
-g Print the group name, or GID # if no group name is available, of the file.
-h option rounds to the nearest whole number unlike the ls implementation of -h which
rounds up always.
-f Print the full path prefix for each file.
-p Print the protections for each file.
tree -f ~+ #只显示目录和文件的绝对路径,注意加上这个: ~+。
tree -pf ~+ #显示目录和文件的绝对路径以及Chmod的权限,注意加上这个: ~+。
tree -pugf ~+ #显示目录和文件的绝对路径以及Chmod的权限,注意加上这个: ~+,u用户,g群组。
==============================================================
FreebsD: Have you tried installing tree with: pkg install tree ,cd /usr/ports/sysutils/tree make install
来自:https://www.reddit.com/r/freebsd/comments/4kxyx1/newbie_having_trouble_using_tree_command/
相关参数说明及常用参数说明:
要想目录和文件有颜色,或是用Tree看有颜色,得用那个SecureCRT做下配置:
Session Options->Terminal->Emulation->Terminal [Linux/Xterm] [V]ANSI Color @老武用的是Linux可以,我用的是Xterm也行,颜色可调一下即可。
常常加 -C,表示颜色,-L表示层级。 如:tree -C -L 2。
-C Turn colorization on always.
阅读全文
php7 memcache 扩展和php7 的redis扩展 。
Php/Js/Shell/Go jack 2016-3-17 17:03
php7 memcache 扩展你们用哪个版本安装成功的?
https://github.com/php-memcached-dev/php-memcached/tree/php7
php7 的redis扩展 有吗?
https://github.com/phpredis/phpredis/tree/php7@tru
https://github.com/php-memcached-dev/php-memcached/tree/php7
php7 的redis扩展 有吗?
https://github.com/phpredis/phpredis/tree/php7@tru
PHP反射类带参数执行反射对象方法传入参数函数示例解析。
Php/Js/Shell/Go jack 2016-3-17 09:05
背景:对于kohana早期框架对类里面的before after以及controller和action的函数均可以用反射类来灵活按既定顺序执行,而在执行的时候假如异常,可以通过PHP提供的异常捕获进行捕获输出,这就涉及到类变对象后其参数的传递问题了,怎么给反射类里面的函数传递多参数乃至引用参数,这个PHP也提供了对应的反射类里函数传入的方法ReflectionMethod::invokeArgs。
使用代码片段如下:
参考更多相关反射的文章:
http://flandycheng.blog.51cto.com/855176/326021/
http://www.phperz.com/article/14/0809/17371.html
自己研究:http://jackxiang.com/post/2090/
ReflectionMethod::invokeArgs
(PHP 5 >= 5.1.0)
ReflectionMethod::invokeArgs — 带参数执行
说明
public mixed ReflectionMethod::invokeArgs ( object $object , array $args )
使用数组给方法传送参数,并执行他。
参数
object
调用方法的对象,如果是静态对象,设置为 null
args
使用 array 传送的方法参数。
返回值
返回方法返回值
错误/异常
如果 object 指定的实例无法执行方法,那么产生 ReflectionException 异常。
如果方法调用失败,产生 ReflectionException
范例
Example #1 ReflectionMethod::invokeArgs() example
<?php
class HelloWorld {
public function sayHelloTo($name) {
return 'Hello ' . $name;
}
}
$reflectionMethod = new ReflectionMethod('HelloWorld', 'sayHelloTo');
echo $reflectionMethod->invokeArgs(new HelloWorld(), array('Mike'));
?>
以上例程会输出:
Hello Mike
注释
Note:
如果函数有参数需为引用,那么它们必须以引用方式传入。
参见
ReflectionMethod::invoke() - Invoke
__invoke()
call_user_func_array() - 调用回调函数,并把一个数组参数作为回调函数的参数
来自:http://help.bitscn.com/php/reflectionmethod.invokeargs.html
使用代码片段如下:
参考更多相关反射的文章:
http://flandycheng.blog.51cto.com/855176/326021/
http://www.phperz.com/article/14/0809/17371.html
自己研究:http://jackxiang.com/post/2090/
ReflectionMethod::invokeArgs
(PHP 5 >= 5.1.0)
ReflectionMethod::invokeArgs — 带参数执行
说明
public mixed ReflectionMethod::invokeArgs ( object $object , array $args )
使用数组给方法传送参数,并执行他。
参数
object
调用方法的对象,如果是静态对象,设置为 null
args
使用 array 传送的方法参数。
返回值
返回方法返回值
错误/异常
如果 object 指定的实例无法执行方法,那么产生 ReflectionException 异常。
如果方法调用失败,产生 ReflectionException
范例
Example #1 ReflectionMethod::invokeArgs() example
<?php
class HelloWorld {
public function sayHelloTo($name) {
return 'Hello ' . $name;
}
}
$reflectionMethod = new ReflectionMethod('HelloWorld', 'sayHelloTo');
echo $reflectionMethod->invokeArgs(new HelloWorld(), array('Mike'));
?>
以上例程会输出:
Hello Mike
注释
Note:
如果函数有参数需为引用,那么它们必须以引用方式传入。
参见
ReflectionMethod::invoke() - Invoke
__invoke()
call_user_func_array() - 调用回调函数,并把一个数组参数作为回调函数的参数
来自:http://help.bitscn.com/php/reflectionmethod.invokeargs.html
背景:这玩意是感觉把rpc的生成变成他自己的了,有点意思,不知底层是不是还是xdr交换统一数据结构,还是php的unpack实现客户端的。
http://www.tuicool.com/articles/NV3Yni3
http://www.tuicool.com/articles/NV3Yni3
背景:对于ip限定缩小范围,最好是采用出口IP通过公司的所有进行放行,而获取用户Ip地址通用方法常见安全隐患(HTTP_X_FORWARDED_FOR)的,所以最好是nginx在代理时就限定死:
deny *.*.*.66;
deny *.*.*.79;
deny *.*.*.80;
deny *.*.*.77;
Nginx的日志的最后一个IP并不安全:
*.*.*.57 - jackxiang.com [15/Mar/2016:18:02:33 +0800] "GET /h5ds/themes/common/mobile/js/maps/swiper.min.js.map HTTP/1.0" 404 20 "-" "Mozilla/5.0 (iPhone; CPU iPhone OS 7_0 like Mac OS X; en-us) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A465 Safari/9537.53" 202.*.*.78
分析过程
这个来自一些项目中,获取用户Ip,进行用户操作行为的记录,是常见并且经常使用的。 一般朋友,都会看到如下通用获取IP地址方法。
function getIP() {
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$realip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
$realip = $_SERVER['HTTP_CLIENT_IP'];
} else {
$realip = $_SERVER['REMOTE_ADDR'];
}
return $realip;
}
这个是网上常见获取,ip函数,用这些值获取IP,我们首先要弄清楚,这些数据是从那个地方传过来的。
IP获取来源
1.’REMOTE_ADDR’ 是远端IP,默认来自tcp 连接是,客户端的Ip。可以说,它最准确,确定是,只会得到直接连服务器客户端IP。如果对方通过代理服务器上网,就发现。获取到的是代理服务器IP了。
如:a->b(proxy)->c ,如果c 通过’REMOTE_ADDR’ ,只能获取到b的IP,获取不到a的IP了。
另外:该IP想篡改将很难实现,在传递知道生成php server值,都是直接生成的。
2.’HTTP_X_FORWARDED_FOR’,’HTTP_CLIENT_IP’ 为了能在大型网络中,获取到最原始用户IP,或者代理IP地址。对HTTp协议进行扩展。定义了实体头。
HTTP_X_FORWARDED_FOR = clientip,proxy1,proxy2 所有IP用”,”分割。 HTTP_CLIENT_IP 在高级匿名代理中,这个代表了代理服务器IP。既然是http协议扩展一个实体头,并且这个值对于传入端是信任的,信任传入方按照规则格式输入的。以下以x_forword_for例子加以说明,正常情况下,这个值变化过程。
来自:http://blog.chacuo.net/98.html
deny *.*.*.66;
deny *.*.*.79;
deny *.*.*.80;
deny *.*.*.77;
Nginx的日志的最后一个IP并不安全:
*.*.*.57 - jackxiang.com [15/Mar/2016:18:02:33 +0800] "GET /h5ds/themes/common/mobile/js/maps/swiper.min.js.map HTTP/1.0" 404 20 "-" "Mozilla/5.0 (iPhone; CPU iPhone OS 7_0 like Mac OS X; en-us) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A465 Safari/9537.53" 202.*.*.78
分析过程
这个来自一些项目中,获取用户Ip,进行用户操作行为的记录,是常见并且经常使用的。 一般朋友,都会看到如下通用获取IP地址方法。
function getIP() {
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$realip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
$realip = $_SERVER['HTTP_CLIENT_IP'];
} else {
$realip = $_SERVER['REMOTE_ADDR'];
}
return $realip;
}
这个是网上常见获取,ip函数,用这些值获取IP,我们首先要弄清楚,这些数据是从那个地方传过来的。
IP获取来源
1.’REMOTE_ADDR’ 是远端IP,默认来自tcp 连接是,客户端的Ip。可以说,它最准确,确定是,只会得到直接连服务器客户端IP。如果对方通过代理服务器上网,就发现。获取到的是代理服务器IP了。
如:a->b(proxy)->c ,如果c 通过’REMOTE_ADDR’ ,只能获取到b的IP,获取不到a的IP了。
另外:该IP想篡改将很难实现,在传递知道生成php server值,都是直接生成的。
2.’HTTP_X_FORWARDED_FOR’,’HTTP_CLIENT_IP’ 为了能在大型网络中,获取到最原始用户IP,或者代理IP地址。对HTTp协议进行扩展。定义了实体头。
HTTP_X_FORWARDED_FOR = clientip,proxy1,proxy2 所有IP用”,”分割。 HTTP_CLIENT_IP 在高级匿名代理中,这个代表了代理服务器IP。既然是http协议扩展一个实体头,并且这个值对于传入端是信任的,信任传入方按照规则格式输入的。以下以x_forword_for例子加以说明,正常情况下,这个值变化过程。
来自:http://blog.chacuo.net/98.html
背景:目前虚拟机和云的兴起,对一些应用的封装啥的还没有火起来,比如:FreeBSD的jail啥的,目前出了一个叫docker的,可以了解了解。
基本概念
Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上。
Docker是一个重新定义了程序开发测试、交付和部署过程的开放平台,Docker则可以称为构建一次,到处运行,这就是docker提出的“Build once,Run anywhere”
备注:java提出的是” compile Once,Run Anywhere”
Docker与linux内核的关系
docker与linux内核的关系
Cgroup: 对资源进行限制(如对物理资源CPU、内存、I/O的限制)
Namespace:对进程进行隔离
Chroot: 能改变当前运行的进程和子进程的根目录
AUFS:联合文件系统,Docker利用AUFS将不同的Layer结合到1个image中去
Docker架构
Docker采用C/S架构,客户端与服务器端不一定要在一起。客户端可以运行在windows、linux等机器上,然后服务器端必须运行在linux 64bit的操作系统上。
Docker“组件间”关系
ü 主机:运行容器的机器
ü 镜像:文件的层次结构,以及包含如何运行容器的元数据, Dockerfile中的每条命令都会在文件系统中创建一个新的层次结构,文件系统在这些层次上构建起来,镜像就构建于这些联合的文件系统之上
ü 容器:一个从镜像中启动,包含正在运行的程序的进程
ü Registry(镜像仓库):存放镜像的地方,如Docker Hub
ü Volumn(卷):将物理机的文件夹挂载到容器内部.与openstack的volumn不一样,openstack中的卷是块存储,不能共享。而这里的volumn可以共享。
ü Dockerfile:用于创建镜像的脚本
Docker应用场景
面向开发人员:快速开发、交付应用程序
主要体现在三个方面:
ü 代码一致:
在没有docker之前,开发、测试、生成环境可能不一样,如发布某个服务的端口时,开发是1000,而生产是2000,这就导致配置文件不一致。然而使用docker后,我在容器内的端口都是一样的,而容器对外暴露的端口可能不一样。
ü 开发环境与生产环境的一致性
我们知道,在生产环境的部署比较复杂,服务非常繁多。通过docker,我们可以单机版上通过容器来模拟生产环境的分布式环境。从而让开发人员的开发更有效率。
ü 快速部署
可以将docker理解为轻量级的虚拟机,启动docker容器速度很快,启动虚拟机很慢。
面向运维人员:降低运维成本
ü 节约安装各种软件的时间。
在没有docker之前,在部署程序之前,势必要搭建环境,而搭建环境很花费时间,还要解决环境的各种依赖,而docker通过镜像机制,将你的代码和运行环境直接打包成镜像,扔到容器启动即可。
ü 降低运维成本。
在没有docker之前,由于技术不断发展,运维也要不停的学习各种软件的使用技能,如Node.js、redis等。有了docker,根本不用关系这些技术(或者少关心),只需要关注容器就可以了,能够正常的发布容器,停止容器、删除容器、迁移容器就可以了。
面向企业: Paas层的实现
Coding.net、Oschina这些代码托管平台,有个功能即提供给用户程序的演示环境,我不知道他们底层到底采用的什么技术,但是如果Iaas层的openstack,给用户直接提供虚拟机,先得太“笨重”,因为虚拟机本身对物理机的开销就比较大,如果采用Docker,我1台物理机可以部署多个容器,可以降低企业的采购物理机的费用,而且运行效率上应该比采用Iaas层的方案快。
Docker基本命令
Docker安装相关命令
参考: https://docs.docker.com/installation/ubuntulinux/
摘自:http://blog.csdn.net/opensure/article/details/46490749
基本概念
Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上。
Docker是一个重新定义了程序开发测试、交付和部署过程的开放平台,Docker则可以称为构建一次,到处运行,这就是docker提出的“Build once,Run anywhere”
备注:java提出的是” compile Once,Run Anywhere”
Docker与linux内核的关系
docker与linux内核的关系
Cgroup: 对资源进行限制(如对物理资源CPU、内存、I/O的限制)
Namespace:对进程进行隔离
Chroot: 能改变当前运行的进程和子进程的根目录
AUFS:联合文件系统,Docker利用AUFS将不同的Layer结合到1个image中去
Docker架构
Docker采用C/S架构,客户端与服务器端不一定要在一起。客户端可以运行在windows、linux等机器上,然后服务器端必须运行在linux 64bit的操作系统上。
Docker“组件间”关系
ü 主机:运行容器的机器
ü 镜像:文件的层次结构,以及包含如何运行容器的元数据, Dockerfile中的每条命令都会在文件系统中创建一个新的层次结构,文件系统在这些层次上构建起来,镜像就构建于这些联合的文件系统之上
ü 容器:一个从镜像中启动,包含正在运行的程序的进程
ü Registry(镜像仓库):存放镜像的地方,如Docker Hub
ü Volumn(卷):将物理机的文件夹挂载到容器内部.与openstack的volumn不一样,openstack中的卷是块存储,不能共享。而这里的volumn可以共享。
ü Dockerfile:用于创建镜像的脚本
Docker应用场景
面向开发人员:快速开发、交付应用程序
主要体现在三个方面:
ü 代码一致:
在没有docker之前,开发、测试、生成环境可能不一样,如发布某个服务的端口时,开发是1000,而生产是2000,这就导致配置文件不一致。然而使用docker后,我在容器内的端口都是一样的,而容器对外暴露的端口可能不一样。
ü 开发环境与生产环境的一致性
我们知道,在生产环境的部署比较复杂,服务非常繁多。通过docker,我们可以单机版上通过容器来模拟生产环境的分布式环境。从而让开发人员的开发更有效率。
ü 快速部署
可以将docker理解为轻量级的虚拟机,启动docker容器速度很快,启动虚拟机很慢。
面向运维人员:降低运维成本
ü 节约安装各种软件的时间。
在没有docker之前,在部署程序之前,势必要搭建环境,而搭建环境很花费时间,还要解决环境的各种依赖,而docker通过镜像机制,将你的代码和运行环境直接打包成镜像,扔到容器启动即可。
ü 降低运维成本。
在没有docker之前,由于技术不断发展,运维也要不停的学习各种软件的使用技能,如Node.js、redis等。有了docker,根本不用关系这些技术(或者少关心),只需要关注容器就可以了,能够正常的发布容器,停止容器、删除容器、迁移容器就可以了。
面向企业: Paas层的实现
Coding.net、Oschina这些代码托管平台,有个功能即提供给用户程序的演示环境,我不知道他们底层到底采用的什么技术,但是如果Iaas层的openstack,给用户直接提供虚拟机,先得太“笨重”,因为虚拟机本身对物理机的开销就比较大,如果采用Docker,我1台物理机可以部署多个容器,可以降低企业的采购物理机的费用,而且运行效率上应该比采用Iaas层的方案快。
Docker基本命令
Docker安装相关命令
参考: https://docs.docker.com/installation/ubuntulinux/
摘自:http://blog.csdn.net/opensure/article/details/46490749
Linux bashrc和profile的用途和区别
Unix/LinuxC技术 jack 2016-3-11 00:41
Linux bashrc和profile的用途和区别
Unix/LinuxC技术 jack 2016-3-10 18:53
聚贤庄中原各路英雄围攻乔峰,主要矛盾是因为乔峰不是汉人。而乔峰使太祖长拳战尽天下英雄而不败就是为了讽刺这些人。
太祖长拳是宋开国皇帝赵匡胤发明的拳术,又名三十二势长拳、宋太祖拳、太祖拳、赵家拳、赵门、太祖门,有的地方也叫红拳、洪拳、炮捶、赵门炮拳。其精神偶像是赵匡胤。明代,该拳法已名闻天下。并对戚家拳、太极拳、洪洞通背拳等拳种产生了重要影响。因此,又有“百拳之母”的称谓。
林,而少林功夫又发源于西域,那些所谓的英雄围攻乔峰是因为他不是汉人,而他们却都用西域功夫,只有乔峰用本朝太祖的长拳,绝妙的讽刺
阅读全文
太祖长拳是宋开国皇帝赵匡胤发明的拳术,又名三十二势长拳、宋太祖拳、太祖拳、赵家拳、赵门、太祖门,有的地方也叫红拳、洪拳、炮捶、赵门炮拳。其精神偶像是赵匡胤。明代,该拳法已名闻天下。并对戚家拳、太极拳、洪洞通背拳等拳种产生了重要影响。因此,又有“百拳之母”的称谓。
林,而少林功夫又发源于西域,那些所谓的英雄围攻乔峰是因为他不是汉人,而他们却都用西域功夫,只有乔峰用本朝太祖的长拳,绝妙的讽刺
阅读全文
Comments starting with '#' are deprecated in Unknown on line 1是因为php-fpm.ini里有#号注释引起的。
Php/Js/Shell/Go jack 2016-3-8 23:25
总之,这种情况主要还是因为php-fpm.conf或php.ini里有#号引起的,我发现尽管php-fpm.conf里用#号能注释,但是会有影响,
我之前安装的是PHP 5.6.18,在运行程序时往往运行nginx请求出现:Comments starting with '#' are deprecated in Unknown on line 1,
后来我再次安装低版本时默认启动没有问题,再将PHP 5.6.18里的php/etc/php-fpm.conf挪动回来后再启动就发生:Comments starting with '#' are deprecated in Unknown on line ,原来里面有一些以#号的中文注释导致的,如:
结论:尽量别用#号注释,php.conf和php-fpm.conf两个,一个是;注释,别用#号,另一个是尽量别用#号,一个#都不要留更好。
===========================================================================
ErrorException [ 8192 ]: Comments starting with '#' are deprecated in Unknown on line 1
find /usr/local/php/ -name "*.ini" -exec sed -i -re 's/^(\s*)#(.*)/\1;\2/g' {} \;
来自:http://stackoverflow.com/questions/29211550/track-down-php-error-comments-starting-with-are-deprecated-in-unknown-on-li
8192 E_DEPRECATED (integer) 运行时通知。启用后将会对在未来版本中可能无法正常工作的代码给出警告。 since PHP 5.3.0
错误码来自:http://www.jb51.net/article/47793.htm
应该是新版本的PHP出现的一个mysql推荐用mysqlli和pdo提示的问题,把错误关掉,再打开就好了,这块儿可能PHP还是有点问题:
error_reporting(E_ALL ^ E_NOTICE ^ E_DEPRECATED);//解决Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future:
ini_set('display_startup_errors', 0);
ini_set('display_errors', 0);
阅读全文
我之前安装的是PHP 5.6.18,在运行程序时往往运行nginx请求出现:Comments starting with '#' are deprecated in Unknown on line 1,
后来我再次安装低版本时默认启动没有问题,再将PHP 5.6.18里的php/etc/php-fpm.conf挪动回来后再启动就发生:Comments starting with '#' are deprecated in Unknown on line ,原来里面有一些以#号的中文注释导致的,如:
结论:尽量别用#号注释,php.conf和php-fpm.conf两个,一个是;注释,别用#号,另一个是尽量别用#号,一个#都不要留更好。
===========================================================================
ErrorException [ 8192 ]: Comments starting with '#' are deprecated in Unknown on line 1
find /usr/local/php/ -name "*.ini" -exec sed -i -re 's/^(\s*)#(.*)/\1;\2/g' {} \;
来自:http://stackoverflow.com/questions/29211550/track-down-php-error-comments-starting-with-are-deprecated-in-unknown-on-li
8192 E_DEPRECATED (integer) 运行时通知。启用后将会对在未来版本中可能无法正常工作的代码给出警告。 since PHP 5.3.0
错误码来自:http://www.jb51.net/article/47793.htm
应该是新版本的PHP出现的一个mysql推荐用mysqlli和pdo提示的问题,把错误关掉,再打开就好了,这块儿可能PHP还是有点问题:
error_reporting(E_ALL ^ E_NOTICE ^ E_DEPRECATED);//解决Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future:
ini_set('display_startup_errors', 0);
ini_set('display_errors', 0);
阅读全文
php __call()方法实现数据库连贯操作
Php/Js/Shell/Go jack 2016-3-8 11:11
背景:对的jquery有一种叫链式操作的dom的,而PHP在写sql时也可以使用类似的方法,如:
这种写法有点类似Jquery的链式写法,如下:
__call函数相关介绍:http://jackxiang.com/post/2834/
=================================================
使用__call()方法来实现数据库连贯操作
---------- 调试PHP ----------
SELECT sex, count(sex) FROM user where sex in ("男","女") group by sex
having avg(age) > 25
Output completed (0 sec consumed) - Normal Termination
来自:http://blog.sina.com.cn/s/blog_6109978501017154.html
这种写法有点类似Jquery的链式写法,如下:
__call函数相关介绍:http://jackxiang.com/post/2834/
=================================================
使用__call()方法来实现数据库连贯操作
---------- 调试PHP ----------
SELECT sex, count(sex) FROM user where sex in ("男","女") group by sex
having avg(age) > 25
Output completed (0 sec consumed) - Normal Termination
来自:http://blog.sina.com.cn/s/blog_6109978501017154.html




