关于shell一些小知识点

关于 [[]] 和 [] 的区别

实例1:

说明:

[]  和 [[]]  是不同的语法;

对于 [

事实上, bash 中没有 [] 语法, [ 是一个命令,出于美观考虑,要求有一个 ] 与之配对; 所以 [ 的前后是要有空格的

对于 [[

[[]] 是bash的内建语法

  1. 如果是 == ,则右边被视为 Pattern; 如果是 =~ ,则右边视为正则; 也就是说,左边和右边是不等价的
  2. [[]] 允许内部 与、或、非; 如: [[ 1 == 1 && 2 == 2 ]]; 而 [] 则不可以,只能: [ 1 == 1 ] && [ 2 == 2 ]

bash基本概念

  1. bash中有保留字(reserved word)和元字符(meta charactor)的区别的,这个很重要
    1. 关键字:
    2. 元字符:
    3. xx
  2. 对于关键字,和其他非元字符的字符都需要用空白字符分开,否则,关键字就识别不出来了; 因为元字符是被特殊对待的,所以,关键字挨着元字符是允许的,所以,如果分不清关键字和元字符的话,就不知道什么时候需要用空白符分隔,什么时候不需要空白符分隔

 

 

man bash

关于元字符、保留字

关于 花括弧

 

命令替换

 

 

docker虚拟机设置固定IP

参考文章: http://www.tuicool.com/articles/v2yQ7bA

创建网桥(可以写成一个脚本):

创建容器

稍微整理一下原作者的命令,写一个脚本:

注: 最新版本的iproute (至少在iproute-3.10.0-54.el7.x86_64 中)支持 -n 选项,功能为:

至少 iproute-3.10.0-21.el7.x86_64 中还没有该选项, 也就是说

等价于

 

如下br1是我做的网桥:

当docker容器stop时,这里的q7443也就消失了,但是网络名字空间中依然会存在; 可以通过 ip netns delete 来删除

 

一种情况,由于我的docker宿主机是virtualbox做的虚拟机,virtualbox虚拟机使用的桥接模式,所以,我这么做出来的docker虚拟机是访问不了外网的;因为,尽管docker虚拟机可以往docker宿主机的网卡上写数据,virtualbox的宿主机上的后台进程也不会发送该数据的(至少不会接受响应的数据)。

 

其实,有一个叫做pipework的工具可以很方便地给容器设置ip; 但是都没有提供卸载容器网卡的功能,有一种比较方便的办法: nsenter 进去 ifdown 就可以了

关于网桥

为什么virtualbox网卡桥接模式下在宿主机上看不到网桥?

virtualbox在后台启动了一个进程,很牛B,能从指定的网卡读取数据和写入数据,如此,就可以做到将某个虚拟机要发送出去的数据写入到指定网卡,而且网卡上收到的传给某个虚拟机(IP)的数据转发给指定虚拟机; 就这么简单。

参考: http://superuser.com/questions/594550/how-does-bridged-networking-work-in-virtualbox

 

 

dnsmasq 的一个小配置

 

 

 

PHP中sessionid的那点儿事儿

PHP中默认的sessionid为PHPSESSID;

当然,也可以通过

string session_name ([ string $name ] )

来修改, 官方说明:

name

The session name references the name of the session, which is used in cookies and URLs (e.g. PHPSESSID). It should contain only alphanumeric characters; it should be short and descriptive (i.e. for users with enabled cookie warnings). If name is specified, the name of the current session is changed to its value.

 

疑问: 只能包含字母和数字?

参考源码:

  1. 不能全数字
  2. 当然,sessionid毕竟是个cookie name,也会遵循cookie name的检查(参看: http://phpor.net/blog/post/1122 )
  3. 没有发现哪里体现“只能包含字母和数字”,实测也发现,其实 dot、_ 都是可以的

 

 

 

php-redis benchmark

脚本:

 

阿里云的1G标准的redis,当同时40个这样的PHP进程压测的话,会有8个进程最终出现select时 1s 超时异常; 但是人家给的指标是支持 300并发的

关于syslog协议

在使用rsyslog的时候,一般来讲,如果消息中含有换行符的话,这条消息会以换行符为分隔,视为多条消息;即: rsyslog协议是基于行处理的,而且,默认单个消息大小为2k(rsyslogd v5),rsyslogd v8默认单个消息大小为8k。

问题: 一般来讲,程序出错时的堆栈信息都是多行的,这种情况该如何处理呢?

办法1: 先将堆栈信息中的换行替换成其它字符

办法2: 其实rsyslog是可以支持换行的,只是不是想换就换的,在structure data中可以小心地换行

 

关于syslog协议有两个rfc:

  1. The BSD syslog Protocol rfc3164
  2. The Syslog Protocol rfc5424

其中:

rfc3164 定义的syslog协议是比较原始的用法,不支持消息的换行

rfc5424 是所谓的version为1的syslog协议,支持 structure data;就是这个structure data中是可以包含换行的; 当然,要严格遵照定义的格式的哦

两种协议格式解析的golang实现: https://github.com/jeromer/syslogparser

 

rsyslog (rsyslog-8.17.0)源码学习:

  1. runtime/stream.c 中是这么解析的

翻译下:

mode=0 单行模式,遇到回车算做消息结束

mode=1 空行分隔模式,遇到空行算作消息结束(就是相邻消息之间要已空行分隔)

mode=2 非空开头模式, 只要下一行空白(应该也包含tab吧)开头就算作上个消息的一部分,不视为新消息

不幸的是,目前发现只有imfile模块才支持这三种模式之间的选择,更不幸的时,imfile模块使用inotify配置时,mode=2有bug(我测试时不是有bug,是根本不能用)

rsyslog disk queue配置

我们是这么使用rsyslog的:

app —-通过/dev/log写入—-> 本地rsyslogd ——–tcp转发(DA Queue)——> 集中日志收集rsyslogd

其中: DA Queue就是如果远程rsyslogd出现问题了,就暂存到本地(先内存后磁盘)

小朋友说配置了DA Queue了,但是一次远程rsyslogd的几个小时的中断过后,日志没能暂存到app端;配置如下:

其实,我们只是使用了local6,我们也只想转发local6的日志到远程rsyslogd;但是,小朋友就是画蛇添足多写了 user.* 这行, 问题就出现在这行;说明: ActionQueue的配置是针对紧挨着的那个转发的配置的,一个ActionQueue的配置不能同时应用到多个转发的配置的。

 

参考资料:http://bigsec.net/one/tool/rsyslog.html

http://my.oschina.net/0757/blog/198329