存档

2013年5月 的存档

vim操作大全

2013年5月28日 没有评论

Linux下命令行模式中打开vim的方式

vim FileName #打开文件 FileName,并将光标置于第一行首
vim +n FileName #打开文件 FileName,并将光标置于第 n 行首
vim + FileName #打开文件 FileName,并将光标置于最后一行
vim + /pattern File #打开文件 File,并将光标置于其中第一个于 pattern 匹配的字符串处
vim –r FileName #在上次正用 vi 编辑 FileName 发生系统崩溃后,恢复FileName
vim File1 … Filen #打开多个文件,依次对之进行编辑
vim -o File1 … Filen #用水平分隔的方式打开多个文件然后进行编辑
vimdiff filename1 filename2 #用垂直分割的方式打开两个文件 filename1,filename2 然后显示出两个文件的不同的比较

插入数据基本操作

行操作:
I #在光标所在行首插入文本
A #在光标所在行尾添加文本
o(open) #在光标所在行下面添加一行
O #在光标所在行上面添加一行
nS #从当前行开始,删除向下 n 行并进入编辑模式,若无 n 删除当前所在行,并进入编辑模式
:r filename #在编辑数据中读入一个文件内容数据,并把这些数据添加到光标所在行后面
字符操作:
i(insert) #在光标前插入文本
a(append) #在光标后插入文本
r(Replace) #替换光标所在处字符,结束替换
R #替换多个字符,以按下 [Esc] 键标志替换结束
ns #从当前光标位置处开始,删除 n 个字符并进入编辑模式,若无 n 删除一个字符,并进入编辑模式
改变某区域:
可以重复的:
[c]+[num]+[ h / j / k / l / w / b / e / ( / ) / { / } / $ / G / /word / ?word / tc / Tc / fc / Fc / c ]
c: #表示改变操作
重复操作次数: #num 表示操作重复次数
操作区域选择:
h #改变光标前一个字符
l #改变光标所在处的字符
j #改变本行与下一行
k #改变本行与上一行
w #改变光标开始到下一个单词词首处
b #改变光标开始到上一个单词词首处
e #改变光标开始到这个单词的结尾处
( #改变光标开始到句子结束处
) #改变光标开始到句子开始处
{ #改变光标开始到段落开始处
} #改变光标开始到段落结束处
$ #改变从光标开始处到行尾处
G #改变从光标所在行到行尾处
/word #改变从光标开始处到下个 word 字符串,不含 word ( word 指代任意字符串,并且可以使用 正则表达式 )
?word #改变从光标开始处到上个 word 字符串,不含 word ( word 指代任意字符串,并且可以使用 正则表达式 )
tc #改变从光标开始处到下个 c 字符处,不含 c ( c 指代任意字符 )
Tc #改变从光标开始处到上个 c 字符处,不含 c ( c 指代任意字符 )
fc #改变从光标开始处到下个 c 字符处,含 c ( c 指代任意字符 )
Fc #改变从光标开始处到上个 c 字符处,含 c ( c 指代任意字符 )
c #改变从光标开始到标记 c 这个位置
不可重复的:
[c]+[ 0 / ^ / H / L]
c: #表示改变操作
操作区域选择:
0 #改变从光标所在处到某一行的开始位置
^ #改变到某一行的第一个字符位置(不包括空格或TAB字符)
L #改变直到屏幕上最后一行的内容
H #改变直到屏幕上第一行的内容
[c]+[i]+[ { / } / ( / ) / ” / ‘ ]
c: #表示改变操作
i: #表示 in 即在里面的意思
操作区域选择:
{ #改变在 {} 中内容( 要求光标在 {} 内 )
} #改变在 {} 中内容( 要求光标在 {} 内 )
[ #改变在 [] 中内容( 要求光标在 [] 内 )
] #改变在 [] 中内容( 要求光标在 [] 内 )
( #改变在 () 中内容( 要求光标在 {} 内 )
) #改变在 () 中内容( 要求光标在 () 内 )
” #改变在 “” 中内容( 要求光标在 “” 内 )
‘ #改变在 ” 中内容( 要求光标在 ” 内 )

保存/退出

:q #退出 vim 返回到 shell,若有修改未被保存,vi 在末行给出提示信息并不退出 vim 到 shell
:q! #退出 vim 返回到 shell,放弃未保存的修改
:wq #保存后退出,无论文件是否有修改,都更新文件的修改时间
😡 #保存后退出,若文件没有修改的话,不更新文件的修改时间
:w #将编辑的数据写入硬盘中
:w! #若文件属性为”只读”时,强制写入该文件
:w filename #写入当前文件到 filename 文件
ZZ #若文件没有更动,则不保存离开,若文件被更动过,则保存后离开
:n1,n2 w filename #将 n1 到 n2 的内容保存到 filename 这个文件中

显示与取消行号,制表符,结尾标志位
:set nu #显示行号,设置之后,会在没一会的前缀显示该行的行号
:set nonu #与 :set nu 相反,为取消行号
:set list #显示制表符(^I)与行尾标志位($)
:set nolist #与 :set list 相反,为取消显示制表符和结尾标志符

光标移动方法

位移
字符操作:
nh / n← #向左移动 n 字符,无 n 移动一字符
nl / n→ #向右移动 n 字符,无 n 移动一字符
n #n 表示“数字”,光标会向右移动这一行 n 个字符.
0 #这是数字 “0”:移动到这一行的最前面字符处
^ #移动到这一行的最开始字符处

行操作:
nj / n↓ #向下移动 n 行,无 n 移动一行
nk / n↑ #向上移动 n 行,无 n 移动一行
[Ctrl+p] #光标上移一行
[Ctrl+n] #光标下移一行
n+ #光标下移到 n 行头,若没有 n 光标移到下行行头
n- #光标上移到 n 行头,若没有 n 光标移到上行行头
n$ #光标下移到 n 行尾,若没有 n 则移动到本行行尾
n_ #向下移动 n-1 行,并光标移动到非空白行首
H #光标移动到这个屏幕的最上方哪一行
M #光标移动到这个屏幕的中央哪一行
L #光标移动到这个屏幕的最下方哪一行
nG #n 为数字.移动到这个文件的第 n 行.若没有 n 则移动到最后一行
gg #移动到这个文件的第一行,相当于 1G
n #向下移动 n 行,无 n 移动一行

跳转
W / w #光标右移一个字至字首.
B / b #光标左移一个字至字首.
E / e #光标右移一个字至字尾.
( #光标移到上个句子句首.
) #光标移到下个句子句首.
{ #光标移到上个段落句首.
} #光标移到下个段落句首.
fc #光标跳转到本行下一个字符 c 处( c 指代任意字符 )
Fc #光标跳转到本行上一个字符 c 处( c 指代任意字符 )
tc #光标跳转到本行下一个字符 c 的前一个字符处( c 指代任意字符 )
Tc #光标跳转到本行上一个字符 c 的后一个字符处( c 指代任意字符 )
/word #光标跳转到下一个字符串 word 处,并把所有 word 单词高亮显示( word 指代任意字符串,并且可以使用 正则表达式 )
?word #光标跳转到上一个字符串 word 处,并把所有 word 单词高亮显示( word 指代任意字符串,并且可以使用 正则表达式 )
# #光标跳转到下个与光标所在处单词相同的单词,并把所有与光标所在处的相同的单词高亮显示
* #光标跳转到上个与光标所在处单词相同的单词,并把所有与光标所在处的相同的单词高亮显示
gd #将与光标所在处的单词相同的单词全部高亮显示,并跳转到上一个高亮显示的单词
gD #将与光标所在处的单词相同的单词全部高亮显示,并跳转到最前面一个高亮显示的单词
. #跳转至上次编辑位置
c #将光标转移到书签 c 处( c 为任意字符 )

下面两个与 / 与 ? 组合着用:
n #下一个匹配(如果是/搜索,则是向下的下一个,?搜索则是向上的下一个,但其实它只会在高亮字符中切换)
N #上一个匹配(同上)

与 f/F 配合使用的命令:
; #重复上一个f命令

复原与重做

[Ctrl+f] #屏幕“向下”移动一页,相当于[Page Down]按键
[Ctrl+b] #屏幕“向上”移动一页,相当于[Page Up]按键
[Ctrl+d] #屏幕“向下”移动半页
[Ctrl+u] #屏幕“向上”移动半页
[Ctrl+e] #屏幕向下滚一行
[Ctrl+y] #屏幕项上滚一行
nz #将第 n 行滚至屏幕顶部。不指定 n 时将当前行滚至屏幕顶
:$ #屏幕滚到文章最后一行
:0 #屏幕滚到文章最开始一行

复制/删除/粘贴
总述
字符操作:
nx #向后删除 n 个字符,若没有 n 向后删除一个字符
nX #向前删除 n 个字符,若没有 n 向前删除一个字符
d0 #那个是数字的 0 ,删除游标所在处,到该行的最前面一个字符
d$ #删除游标所在处,到该行的最后一个字符
y0 #复制光标所在的那个字符到该行行首的所有数据
y$ #复制光标所在的那个字符到该行行尾的所有数据
p #将已复制的数据在光标下一列贴上
P #将已复制的数据在光标上一列贴上

行操作:
ndd #删除光标所在的向下 n 列,若没有 n 删除游标所在的那一整列
dnG #删除光标所在到第 n 行的所有数据,若没有 n 删除光标所在到最后一行的所有数据
nyy #复制光标所在的向下 n 行,若无 n 复制游标所在的那一行
ynG #复制游标所在列到第n行的所有数据,若无 n 复制游标所在行到最后一行的所有数据
J #将光标所在列与下一列的数据结合成同一列

删除某区域:
可以重复的:
[d]+[num]+[ h / j / k / l / w / b / e / ( / ) / { / } / $ / G / /word / ?word / tc / Tc / fc / Fc / c ]
d: #表示删除操作
重复操作次数: #num 表示操作重复次数
操作区域选择:
h #删除光标前一个字符
l #删除光标所在处的字符
j #删除本行与下一行
k #删除本行与上一行
w #删除光标开始到下一个单词词首处
b #删除光标开始到上一个单词词首处
e #删除光标开始到这个单词的结尾处
( #删除光标开始到句子结束处
) #删除光标开始到句子开始处
{ #删除光标开始到段落开始处
} #删除光标开始到段落结束处
$ #删除从光标开始处到行尾处
G #删除从光标所在行到行尾处
/word #删除从光标开始处到下个 word 字符串,不含 word ( word 指代任意字符串,并可以使用 正则表达式 )
?word #删除从光标开始处到上个 word 字符串,不含 word ( word 指代任意字符串,并且可以使用 正则表达式 )
tc #删除从光标开始处到下个 c 字符处,不含 c ( c 指代任意字符 )
Tc #删除从光标开始处到上个 c 字符处,不含 c ( c 指代任意字符 )
fc #删除从光标开始处到下个 c 字符处,含 c ( c 指代任意字符 )
Fc #删除从光标开始处到上个 c 字符处,含 c ( c 指代任意字符 )
c #删除从光标开始到标记 c 这个位置
不可重复的:
[d]+[ 0 / ^ / H / L / { / }[ / ]( / ) / ” / ‘]
d: #表示删除操作
操作区域选择:
0 #删除从光标所在处到某一行的开始位置
^ #删除到某一行的第一个字符位置(不包括空格或TAB字符)
L #删除直到屏幕上最后一行的内容
H #删除直到屏幕上第一行的内容
[d]+[i]+[ { / }[ / ]( / ) / ” / ‘]
d: #表示删除操作
i: #表示 in 即在里面的意思
操作区域选择:
{ #删除在 {} 中内容( 要求光标在 {} 内 )
} #删除在 {} 中内容( 要求光标在 {} 内 )
[ #删除在 [] 中内容( 要求光标在 [] 内 )
] #删除在 [] 中内容( 要求光标在 [] 内 )
( #删除在 () 中内容( 要求光标在 {} 内 )
) #删除在 () 中内容( 要求光标在 () 内 )
” #删除在 “” 中内容( 要求光标在 “” 内 )
‘ #删除在 ” 中内容( 要求光标在 ” 内 )

复制某区域:
可以重复的:
[y]+[num]+[ h / j / k / l / w / b / e / ( / ) / { / } / $ / G / /word / ?word / tc / Tc / fc / Fc / c ]
y: #表示复制操作
重复操作次数: #num 表示操作重复次数
操作区域选择:
h #复制光标前一个字符
l #复制光标所在处的字符
j #复制本行与下一行
k #复制本行与上一行
w #复制光标开始到下一个单词词首处
b #复制光标开始到上一个单词词首处
e #复制光标开始到这个单词的结尾处
( #复制光标开始到句子结束处
) #复制光标开始到句子开始处
{ #复制光标开始到段落开始处
} #复制光标开始到段落结束处
$ #复制从光标开始处到行尾处
G #复制从光标所在行到行尾处
/word #复制从光标开始处到下个 word 字符串,不含 word ( word 指代任意字符串,并且可以使用 正则表达式 )
?word #复制从光标开始处到上个 word 字符串,不含 word ( word 指代任意字符串,并且可以使用 正则表达式 )
tc #复制从光标开始处到下个 c 字符处,不含 c ( c 指代任意字符 )
Tc #复制从光标开始处到上个 c 字符处,不含 c ( c 指代任意字符 )
fc #复制从光标开始处到下个 c 字符处,含 c ( c 指代任意字符 )
Fc #复制从光标开始处到上个 c 字符处,含 c ( c 指代任意字符 )
c #复制从光标开始到标记 c 这个位置
不可重复的:
[y]+[ 0 / ^ / H / L]
y: #表示复制操作
操作区域选择:
0 #复制从光标所在处到某一行的开始位置
^ #复制到某一行的第一个字符位置(不包括空格或TAB字符)
L #复制直到屏幕上最后一行的内容
H #复制直到屏幕上第一行的内容
[y]+[i]+[ { / } / ( / ) / ” / ‘ ]
y: #表示复制操作
i: #表示 in 即在里面的意思
操作区域选择:
{ #复制在 {} 中内容( 要求光标在 {} 内 )
} #复制在 {} 中内容( 要求光标在 {} 内 )
[ #复制在 [] 中内容( 要求光标在 [] 内 )
] #复制在 [] 中内容( 要求光标在 [] 内 )
( #复制在 () 中内容( 要求光标在 {} 内 )
) #复制在 () 中内容( 要求光标在 () 内 )
” #复制在 “” 中内容( 要求光标在 “” 内 )
‘ #复制在 ” 中内容( 要求光标在 ” 内 )

高亮显示

/word #将光标跳转到下一个字符串 word 处,并把所有 word 单词高亮显示( word 指代任意字符串,并且可以使用 正则表达式 )
?word #将光标跳转到上一个字符串 word 处,并把所有 word 单词高亮显示( word 指代任意字符串,并且可以使用 正则表达式 )
gd #将与光标所在处的单词相同的单词全部高亮显示,并跳转到上一个高亮显示的单词
gD #将与光标所在处的单词相同的单词全部高亮显示,并跳转到最前面一个高亮显示的单词
# #光标跳转到下个与光标所在处单词相同的单词,并把所有与光标所在处的相同的单词高亮显示
* #光标跳转到上个与光标所在处单词相同的单词,并把所有与光标所在处的相同的单词高亮显示
:nohl #取消高亮显示

行移动操作

>> #将当前行右移一个单位
<< #将当前行左移一个单位(一个tab符)
== #自动缩进当前行

书签

mc #把当前位置记录为书签 c ( c 为任意字符 )
#当定义多个位置的标签为一样时,只有最后一个定义的位置标签会生效
`c #将光标转移到书签 c 处( c 为任意字符 )

十六进制查看文本内容

%!xxd #按十六进制查看当前文件
%!xxd -r #从十六进制返回正常模式

自动补全

[Ctrl+n] #自动补全(前提是以前打过的单词)
[Ctrl+p] #自动补全(前提是以前打过的单词)

标记文本

进入标记文本模式
v #进入标记文本模式,单字符模式
V #进入标记文本模式,行模式
[ctrl+v] #进入标记文本模式,列模式,类似于UE的列模式

对标记文本模式中区域选择
aw #选中一个单词,含单词后的空格
as #选中一个句子,含句号后的空格
ap #选中一个段落,含段落后的空格
ab #选中()括号中的所有内容,含()
aB #选中{}括号中的所有内容,含{}
iw #选中一个单词,不含单词后的空格
is #选中一个句子,不含句号后的空格
ip #选中一个段落,不含段落后的空格
ib #选中()括号中的内容,不含()
iB #选中{}括号中的内容,不含{}
除此之外还有上面光标移动的方法,但是要除去组合键,如:[ctrl]+[p]

移动标记文本模式中光标位置
o #光标在选择区域中的对角线之间的跳转
O #光标在选择区域中的横纵之间的跳转
当在 V 与 [ctrl]+[v] 模式中
我们除了 o,O 来移动光标位置外,还可以通过移动光标位置中一些方法来移动光标位置(不是所有而是其中一些)

对标记文本模式中数据操作
~ #将选中块中的内容大小写翻转
u #将选中块中的内容转成小写
U #将选中块中的内容转成大写
y #复制选中块中的内容
d/D/x/X #删除选中块中的内容

窗口操作

:vne [filename] #打开文件 filename,并把光标所在窗口沿横向分为两个窗口
:sp [filename] #打开文件 filename,并把光标所在窗口沿纵向分为两个窗口
:S [filename] #打开文件 filename,并把光标所在窗口沿纵向分为两个窗口
:new [filename] #打开文件 filename,并把光标所在窗口沿纵向分为两个窗口
************************************************************
在 new 前面可以加的参数:
leftabove #当前窗口的左上方
aboveleft #同上
rightbelow #当前窗口的右下方
belowright #同上
topleft #整个 Vim 窗口的最上面或者最左边
botright #整个 Vim 窗口的最下面或者最右边
************************************************************
:only #关闭除了编辑以外的窗口,但是那些窗口中要是有文本被改写过并且没有保存那么操作将失败
:close #关闭编辑窗口,如果编辑窗口文本修改过且未保存,或编辑窗口为唯一窗口的话,操作失败
:vertical diffsplit [file] #纵向为 file 开个新的编辑窗口,并且比较原编辑文件和 file 编辑文件的不同
:diffsplit [file] #横向为 file 开个新的编辑窗口,并且比较原编辑文件和 file 编辑文件的不同
:res -n #窗口高度减小n
:res +n #窗口高度增大n
[ctrl+w]+[=] #窗口等宽
[ctrl+w]+[h] #将光标移动到左方的窗口
[ctrl+w]+[←] #将光标移动到左方的窗口
[ctrl+w]+[l] #将光标移动到右方的窗口
[ctrl+w]+[→] #将光标移动到右方的窗口
[ctrl+w]+[j] #将光标移动到下方的窗口
[ctrl+w]+[↓] #将光标移动到下方的窗口
[ctrl+w]+[k] #将光标移动到上方的窗口
[ctrl+w]+[↑] #将光标移动到上方的窗口
[ctrl+w]+[t] #将光标移动到最上方的窗口
[ctrl+w]+[b] #将光标移动到最下方的窗口
[ctrl+w]+[ctrl+r] #将光标所在窗口下移
[ctrl+w]+[q] #退出光标所在窗口,相当于在光标所在窗口的命令行模式中输入:q
[ctrl+w]+[+] #扩大所在窗口
[ctrl+w]+[-] #缩小所在窗口

对所有窗口执行命令

:qall #退出所有窗口,但是如果你有一个窗口发生改写但未保存 vim 是不会退出的
:wall #保存所有修改过的窗口
:wqall #保存所有修改过的窗口并关闭,然后退出 vim
:qall! #强制退出所有窗口,然后退出 vim

多档案编辑

:n #编辑下一个档案
:N #编辑上一个档案
:files #列出目前这个 vim 的开启的所有档案

执行 shell 命令

:sh #打开 shell,可执行shell命令,输入exit退出shell返回到vim
:!cmd #直接执行 shell ( cmd 表示为任意 shell 命令 )

命令行下行操作

:n1,n2 co n3 #将 n1 行到 n2 行之间的内容拷贝到第 n3 行下.若无『 ,n2』则复制 n1 到 n3 行下
:n1,n2 m m3 #移动 n1 行到 n2 行之间的内容移至第 n3 行下.若无『 ,n2』则将 n1 内容移到 n3 行下
:n1,n2 d #删除 n1 行到 n2 行之间的内容,『 ,n2』则将 n1 行删除
:n1,n2 y #复制 n1 行到 n2 行之间的内容,『 ,n2』则将 n1 行复制
:[range]s/{pattern}/{string}/[flag] [count] #字符替换
************************************************************
格式说明:
range #表示行数
% #表示所有行
n1,n2 #表示由 n1 行到 n2 行之间,若无 n2 则表示在 n1 行处
s #表示substitution,替换的意思
pattern #表示被替换的字符串
string #表示替换的字符串
flag #表示标志,取值g,i,c等
g #表示global,全部
i #表示ignore,忽略大小写
c #表示confirm,一个一个交互确认替换
count #表示从当前行到接下来的第几行,表示范围
**************************************************************

 

 

 

分类: linux 标签:

Salt Full list of builtin execution modules

2013年5月24日 没有评论

Virtual modules

aliases Manage the information in the aliases file
alternatives salt.modules.alternatives
apache Support for Apache
apt Support for APT (Advanced Packaging Tool)
archive A module to wrap archive calls
at Wrapper module for at(1)
augeas_cfg Manages configuration files via augeas
bluez Support for Bluetooth (using Bluez in Linux)
brew Homebrew for Mac OS X
butterkvm Specialized routines used by the butter cloud component
cassandra Cassandra NoSQL Database Module
cmdmod A module for shelling out
config Return config information
cp Minion side functions for salt-cp
cron Work with cron
daemontools daemontools service module. This module will create daemontools type
darwin_sysctl Module for viewing and modifying sysctl parameters
data Manage a local persistent data structure that can hold any arbitrary data
debconfmod Support for Debconf
debian_service Service support for Debian systems – uses update-rc.d and service to modify the
disk Module for gathering disk information
djangomod Manage Django sites
dnsmasq Module for managing dnqmasq
dnsutil Compendium of generic DNS utilities
dpkg Support for DEB packages
ebuild Support for Portage
eix Support for Eix
event Fire events on the minion, events can be fired up to the master
extfs Module for managing ext2/3/4 file systems
file Manage information about files on the minion, set/read user, group, and mode
freebsdjail The jail module for FreeBSD
freebsdkmod Module to manage FreeBSD kernel modules
freebsdpkg Package support for FreeBSD
freebsdservice The service module for FreeBSD
freebsd_sysctl Module for viewing and modifying sysctl parameters
gem Manage ruby gems.
gentoolkitmod Support for Gentoolkit
gentoo_service Top level package command wrapper, used to translate the os detected by the
git Support for the Git SCM
glance Module for handling openstack glance calls.
grains Control aspects of the grains data
groupadd Manage groups on Linux and OpenBSD
grub_legacy Support for GRUB Legacy
guestfs Interact with virtual machine images via libguestfs
hg Support for the Mercurial SCM
hosts Manage the information in the hosts file
img Virtual machine image management tools
iptables Support for iptables
keyboard Module for managing keyboards on POSIX-like systems.
key Functions to view the minion’s public key information
keystone Module for handling openstack keystone calls.
kmod Module to manage Linux kernel modules
kvm_hyper Provide the hyper module for kvm hypervisors.
launchctl Module for the management of MacOS systems that use launchd/launchctl
layman Support for Layman
ldapmod Module to provide LDAP commands via salt.
linux_acl Support for Linux File Access Control Lists
linux_lvm Support for Linux LVM2
linux_sysctl Module for viewing and modifying sysctl parameters
locale Module for managing locales on POSIX-like systems.
locate Module for using the locate utilities
logrotate Module for managing logrotate.
makeconf Support for modifying make.conf under Gentoo
match The match module allows for match routines to be run and determine target
mdadm Salt module to manage RAID arrays with mdadm
mine The function cache system allows for data to be stored on the master so it
mongodb Module to provide MongoDB functionality to Salt
monit Monit service module.
moosefs Module for gathering and managing information about MooseFS
mount Salt module to manage unix mounts and the fstab file
munin Run munin plugins/checks from salt and format the output as data.
mysql Module to provide MySQL compatibility to salt.
network Module for gathering and managing network information
nfs3 Module for managing NFS version 3.
nginx Support for nginx
nova Module for handling openstack nova calls.
npm Manage and query NPM packages.
nzbget Support for nzbget
openbsdpkg Package support for OpenBSD
openbsdservice The service module for OpenBSD
osxdesktop Mac OS X implementations of various commands in the “desktop” interface
pacman A module to wrap pacman calls, since Arch is the best
pam Support for pam
parted Module for managing partitions on POSIX-like systems.
pecl Manage PHP pecl extensions.
pillar Extract the pillar data for this minion
pip Install Python packages with pip to either the system or a virtualenv
pkgng Support for pkgng
pkg_resource Resources needed by pkg providers
pkgutil Pkgutil support for Solaris
postgres Module to provide Postgres compatibility to salt.
poudriere Support for poudriere
ps A salt interface to psutil, a system and process library.
publish Publish a command from a minion to a target
puppet Execute puppet routines
pw_group Manage groups on FreeBSD
pw_user Manage users with the useradd command
qemu_img Qemu-img Command Wrapper
qemu_nbd Qemu Command Wrapper
quota Module for managing quotas on POSIX-like systems.
rabbitmq Module to provide RabbitMQ compatibility to Salt.
reg Manage the registry on Windows
ret Module to integrate with the returner system and retrieve data sent to a salt
rh_ip The networking module for RHEL/Fedora based distros
rh_service Service support for RHEL-based systems. This interface uses the service and
rpm Support for rpm
rvm Manage ruby installations and gemsets with RVM, the Ruby Version Manager.
s3 Connection module for Amazon S3
saltutil The Saltutil module is used to manage the state of the salt minion itself. It
selinux Execute calls on selinux
service The default service module, if not otherwise specified salt will fall back
shadow Manage the shadow file
smf Service support for Solaris 10 and 11, should work with other systems
solaris_group Manage groups on Solaris
solarispkg Package support for Solaris
solaris_shadow Manage the shadow file
solaris_user Manage users with the useradd command
solr Apache Solr Salt Module
sqlite3 Support for SQLite3
ssh Manage client ssh components
state Control the state system on the minion
status Module for returning various status data about a minion.
supervisord Provide the service module for supervisord
svn Subversion SCM
sysbench The ‘sysbench’ module is used to analyse the
sysmod The sys module provides information about the available functions on the
systemd Provide the service module for systemd
system Support for reboot, shutdown, etc
test Module for running arbitrary tests
timezone Module for managing timezone on POSIX-like systems.
tls A salt module for SSL/TLS.
tomcat Support for Tomcat
upstart Module for the management of upstart systems.
useradd Manage users with the useradd command
virt Work with virtual machines managed by libvirt
virtualenv Create virtualenv environments
win_disk Module for gathering disk information on Windows
win_file Manage information about files on the minion, set/read user, group
win_groupadd Manage groups on Windows
win_network Module for gathering and managing network information
win_pkg A module to manage software on Windows
win_service Windows Service module.
win_shadow Manage the shadow file
win_status Module for returning various status data about a minion.
win_useradd Manage Windows users with the net user command
yumpkg5 Support for YUM
yumpkg Support for YUM
zpool zfs support.
zypper Package support for openSUSE via the zypper package manager
分类: salt 标签:

Redis几个认识误区

2013年5月22日 没有评论

 

1. Redis是什么

这个问题的结果影响了我们怎么用Redis。如果你认为Redis是一个key value store, 那可能会用它来代替MySQL;如果认为它是一个可以持久化的cache, 可能只是它保存一些频繁访问的临时数据。Redis是REmote DIctionary Server的缩写,在Redis在官方网站的的副标题是A persistent key-value database with built-in net interface written in ANSI-C for Posix systems,这个定义偏向key value store。还有一些看法则认为Redis是一个memory database,因为它的高性能都是基于内存操作的基础。另外一些人则认为Redis是一个data structure server,因为Redis支持复杂的数据特性,比如List, Set等。对Redis的作用的不同解读决定了你对Redis的使用方式。

互联网数据目前基本使用两种方式来存储,关系数据库或者key value。但是这些互联网业务本身并不属于这两种数据类型,比如用户在社会化平台中的关系,它是一个list,如果要用关系数据库存储就需要转换成一种多行记录的形式,这种形式存在很多冗余数据,每一行需要存储一些重复信息。如果用key value存储则修改和删除比较麻烦,需要将全部数据读出再写入。Redis在内存中设计了各种数据类型,让业务能够高速原子的访问这些数据结构,并且不需要关心持久存储的问题,从架构上解决了前面两种存储需要走一些弯路的问题。

2. Redis不可能比Memcache快

很多开发者都认为Redis不可能比Memcached快,Memcached完全基于内存,而Redis具有持久化保存特性,即使是异步的,Redis也不可能比Memcached快。但是测试结果基本是Redis占绝对优势。一直在思考这个原因,目前想到的原因有这几方面。

  • Libevent。和Memcached不同,Redis并没有选择libevent。Libevent为了迎合通用性造成代码庞大(目前Redis代码还不到libevent的1/3)及牺牲了在特定平台的不少性能。Redis用libevent中两个文件修改实现了自己的epoll event loop(4)。业界不少开发者也建议Redis使用另外一个libevent高性能替代libev,但是作者还是坚持Redis应该小巧并去依赖的思路。一个印象深刻的细节是编译Redis之前并不需要执行./configure。
  • CAS问题。CAS是Memcached中比较方便的一种防止竞争修改资源的方法。CAS实现需要为每个cache key设置一个隐藏的cas token,cas相当value版本号,每次set会token需要递增,因此带来CPU和内存的双重开销,虽然这些开销很小,但是到单机10G+ cache以及QPS上万之后这些开销就会给双方相对带来一些细微性能差别(5)。

3. 单台Redis的存放数据必须比物理内存小

Redis的数据全部放在内存带来了高速的性能,但是也带来一些不合理之处。比如一个中型网站有100万注册用户,如果这些资料要用Redis来存储,内存的容量必须能够容纳这100万用户。但是业务实际情况是100万用户只有5万活跃用户,1周来访问过1次的也只有15万用户,因此全部100万用户的数据都放在内存有不合理之处,RAM需要为冷数据买单。

这跟操作系统非常相似,操作系统所有应用访问的数据都在内存,但是如果物理内存容纳不下新的数据,操作系统会智能将部分长期没有访问的数据交换到磁盘,为新的应用留出空间。现代操作系统给应用提供的并不是物理内存,而是虚拟内存(Virtual Memory)的概念。

基于相同的考虑, 2.0也增加了VM特性。让Redis数据容量突破了物理内存的限制。并实现了数据冷热分离。

4. Redis的VM实现是重复造轮子

Redis的VM依照之前的epoll实现思路依旧是自己实现。但是在前面操作系统的介绍提到OS也可以自动帮程序实现冷热数据分离,Redis只需要OS申请一块大内存,OS会自动将热数据放入物理内存,冷数据交换到硬盘,另外一个知名的“理解了现代操作系统(3)”的Varnish就是这样实现,也取得了非常成功的效果。

作者antirez在解释为什么要自己实现VM中提到几个原因(6)。主要OS的VM换入换出是基于Page概念,比如OS VM1个Page是4K, 4K中只要还有一个元素即使只有1个字节被访问,这个页也不会被SWAP, 换入也同样道理,读到一个字节可能会换入4K无用的内存。而Redis自己实现则可以达到控制换入的粒度。另外访问操作系统SWAP内存区域时block进程,也是导致Redis要自己实现VM原因之一。

5. 用get/set方式使用Redis

作为一个key value存在,很多开发者自然的使用set/get方式来使用Redis,实际上这并不是最优化的使用方法。尤其在未启用VM情况下,Redis全部数据需要放入内存,节约内存尤其重要。

假如一个key-value单元需要最小占用512字节,即使只存一个字节也占了512字节。这时候就有一个设计模式,可以把key复用,几个key-value放入一个key中,value再作为一个set存入,这样同样512字节就会存放10-100倍的容量。

这就是为了节约内存,建议使用hashset而不是set/get的方式来使用Redis,详细方法见参考文献(7)。

6. 使用aof代替snapshot

Redis有两种存储方式,默认是snapshot方式,实现方法是定时将内存的快照(snapshot)持久化到硬盘,这种方法缺点是持久化之后如果出现crash则会丢失一段数据。因此在完美主义者的推动下作者增加了aof方式。aof即append only mode,在写入内存数据的同时将操作命令保存到日志文件,在一个并发更改上万的系统中,命令日志是一个非常庞大的数据,管理维护成本非常高,恢复重建时间会非常长,这样导致失去aof高可用性本意。另外更重要的是Redis是一个内存数据结构模型,所有的优势都是建立在对内存复杂数据结构高效的原子操作上,这样就看出aof是一个非常不协调的部分。

其实aof目的主要是数据可靠性及高可用性,在Redis中有另外一种方法来达到目的:Replication。由于Redis的高性能,复制基本没有延迟。这样达到了防止单点故障及实现了高可用。

小结

要想成功使用一种产品,我们需要深入了解它的特性。Redis性能突出,如果能够熟练的驾驭,对国内很多大型应用具有很大帮助。希望更多同行加入到Redis使用及代码研究行列。

参考文献

  1. On Designing and Deploying Internet-Scale Service(PDF)
  2. Facebook’s New Real-Time Messaging System: HBase To Store 135+ Billion Messages A Month
  3. What’s wrong with 1975 programming
  4. Linux epoll is now supported(Google Groups)
  5. CAS and why I don’t want to add it to Redis(Google Groups)
  6. Plans for Virtual Memory(Google Groups)
  7. Full of keys(Salvatore antirez Sanfilippo)

转载自:http://www.w3ccollege.org/redis/redis-some-misunderstandings.html

分类: Redis 标签:

linux shell基础

2013年5月21日 没有评论

语法基本介绍

开头

程序必须以下面的行开始(必须放在文件的第一行):
#!/bin/sh
符号#!用来告诉系统它后面的参数是用来执行该文件的程序。在这个例子中我们使用/bin/sh来执行程序。  当编辑好脚本时,如果要执行该脚本,还必须使其可执行。
要使脚本可执行:   编译 chmod +x filename 这样才能用./filename 来运行

注释

在进行shell编程时,以#开头的句子表示注释,直到这一行的结束。我们真诚地建议您在程序中使用注释。如果您使用了注释,那么即使相当长的时间内没有使用该脚本,您也能在很短的时间内明白该脚本的作用及工作原理。

变量

在其他编程语言中您必须使用变量。在shell编程中,所有的变量都由字符串组成,并且您不需要对变量进行声明。要赋值给一个变量,您可以这样写:

 

环境变量

由export关键字处理过的变量叫做环境变量。我们不对环境变量进行讨论,因为通常情况下仅仅在登录
脚本中使用环境变量。

Shell命令和流程控制

在shell脚本中可以使用三类命令:

Unix 命令:

虽然在shell脚本中可以使用任意的unix命令,但是还是由一些相对更常用的命令。这些命令通常是用来进行文件和文字操作的。
常用命令语法及功能

 

 概念: 管道, 重定向和 backtick

这些不是系统命令,但是他们真的很重要。
管道 (|) 将一个命令的输出作为另外一个命令的输入。
grep “hello” file.txt | wc -l
在file.txt中搜索包含有”hello”的行并计算其行数。
在这里grep命令的输出作为wc命令的输入。当然您可以使用多个命令。
重定向:将命令的结果输出到文件,而不是标准输出(屏幕)。
> 写入文件并覆盖旧文件
>> 加到文件的尾部,保留旧文件内容。

反短斜线

使用反短斜线可以将一个命令的输出作为另外一个命令的一个命令行参数。
命令:
find . -mtime -1 -type f -print
用来查找过去24小时(-mtime –2则表示过去48小时)内修改过的文件。如果您想将所有查找到的文件打一个包,则可以使用以下脚本:
#!/bin/sh
# The ticks are backticks () not normal quotes (‘):
tar -zcvf lastmod.tar.gz
find . -mtime -1 -type f -print

流程控制

if

”if” 表达式 如果条件为真则执行then后面的部分:
if ….; then
….
elif ….; then
….
else
….
fi
大多数情况下,可以使用测试命令来对条件进行测试。比如可以比较字符串、判断文件是否存在及是否可读等等…
通常用” [ ] “来表示条件测试。注意这里的空格很重要。要确保方括号的空格。
[ -f "somefile" ] :判断是否是一个文件
[ -x "/bin/ls" ] :判断/bin/ls是否存在并有可执行权限
[ -n "$var" ] :判断$var变量是否有值
[ "$a" = "$b" ] :判断$a和$b是否相等
执行man test可以查看所有测试表达式可以比较和判断的类型。
直接执行以下脚本:

 

变量$SHELL包含了登录shell的名称,我们和/bin/bash进行了比较。

熟悉C语言的朋友可能会很喜欢下面的表达式:
[ -f "/etc/shadow" ] && echo “This computer uses shadow passwors”
这里 && 就是一个快捷操作符,如果左边的表达式为真则执行右边的语句。您也可以认为是逻辑运算中的与操作。上例中表示如果/etc/shadow文件存在则打印” This computer uses shadow passwors”。同样或操作(||)在shell编程中也是可用的。这里有个例子:

该脚本首先判断mailfolder是否可读。如果可读则打印该文件中的”From” 一行。如果不可读则或操作生效,打印错误信息后脚本退出。这里有个问题,那就是我们必须有两个命令:
-打印错误信息
-退出程序
我们使用花括号以匿名函数的形式将两个命令放到一起作为一个命令使用。一般函数将在下文提及。
不用与和或操作符,我们也可以用if表达式作任何事情,但是使用与或操作符会更便利很多。

case

case :表达式可以用来匹配一个给定的字符串,而不是数字。
case … in
…) do something here ;;
esac
让我们看一个例子。 file命令可以辨别出一个给定文件的文件类型,比如:
file lf.gz
这将返回:
lf.gz: gzip compressed data, deflated, original filename,
last modified: Mon Aug 27 23:09:18 2001, os: Unix
我们利用这一点写了一个叫做smartzip的脚本,该脚本可以自动解压bzip2, gzip 和zip 类型的压缩文件:
#!/bin/sh
ftype=
file “$1″
case “$ftype” in
”$1: Zip archive”*)
unzip “$1″ ;;
“$1: gzip compressed”*)
gunzip “$1″ ;;
”$1: bzip2 compressed”*)
bunzip2 “$1″ ;;
*) echo “File $1 can not be uncompressed with smartzip”;;
esac
您可能注意到我们在这里使用了一个特殊的变量$1。该变量包含了传递给该程序的第一个参数值。
也就是说,当我们运行:
smartzip articles.zip
$1 就是字符串 articles.zip

selsect

select 表达式是一种bash的扩展应用,尤其擅长于交互式使用。用户可以从一组不同的值中进行选择。
select var in … ; do
break
done
…. now $ var can be used ….
下面是一个例子:
#!/bin/sh
echo “What is your favourite OS?”
select var in “Linux” “Gnu Hurd” “Free BSD” “Other”; do
break
done
echo “You have selected $var”
下面是该脚本运行的结果:
What is your favourite OS?
1) Linux
2) Gnu Hurd
3) Free BSD
4) Other
#? 1
You have selected Linux
注:var是个变量,可以换成其它的值。break用来跳出循环,如果没有break则一直循环下去。done与select对应。

loop

loop表达式:
while …; do
….
done
while-loop 将运行直到表达式测试为真。will run while the expression that we test for is true.
关键字”break” 用来跳出循环。而关键字”continue”用来不执行余下的部分而直接跳到下一个循环。

for-loop表达式查看一个字符串列表 (字符串用空格分隔) 然后将其赋给一个变量:
1,   for var in ….; do
….
done
在下面的例子中,将分别打印ABC到屏幕上:
#!/bin/sh
for var in A B C ; do
echo “var is $var”
done

2,   for (( 条件一; 条件二; 条件三 );do

done
例:

for ((i=1;i<10;i=$[$i+1]));do

echo “a”
done
输出:

a
a
a
a
a
a
a
a
a

条件一:这可以看成是『初始值』,如上面的例子中,初始值是 i=1 啦!
条件二:这可以看成是『符合值』,如上面的例子中,当 i<=100 的时候都是符合条件的!
条件三:这可以看成是『步阶』!也就是说, i 每次都加一! 所以啦!上面的例子是说:由 i=1 开始到 i<= 100 ,每次 i 都加一来执行底下的程序段(就是 s=s+i ),当 i >100 (也就是 i=101 )就跳出这一段程序段!怎样!不难吧!

下面是一个更为有用的脚本showrpm,其功能是打印一些RPM包的统计信息:
#!/bin/sh
# list a content summary of a number of RPM packages
# USAGE: showrpm rpmfile1 rpmfile2 …
# EXAMPLE: showrpm /cdrom/RedHat/RPMS/*.rpm
for rpmpackage in $*; do
if [ -r "$rpmpackage" ];then
echo “=============== $rpmpackage ==============”
rpm -qi -p $rpmpackage
else
echo “ERROR: cannot read file $rpmpackage”
fi
done
这里出现了第二个特殊的变量$*,该变量包含了所有输入的命令行参数值。
如果您运行showrpm openssh.rpm w3m.rpm webgrep.rpm
此时 $* 包含了 3 个字符串,即openssh.rpm, w3m.rpm and webgrep.rpm.

『until:直到条件相同的时候才离开程序』;
『while:当条件相同的时候,就继续做!』

until [ condition1 ] && { || } [ condition2 ] …

引号

在向程序传递任何参数之前,程序会扩展通配符和变量。这里所谓扩展的意思是程序会把通配符(比如*)替换成合适的文件名,它变量替换成变量值。为了防 止程序作这种替换,您可以使用引号:让我们来看一个例子,假设在当前目录下有一些文件,两个jpg文件, mail.jpg 和tux.jpg。
编译SHELL脚本
#ch#!/bin/sh mod +x filename
cho *.jpg       ./filename 来执行您的脚本。
这将打印出”mail.jpg tux.jpg”的结果。
引号 (单引号和双引号) 将防止这种通配符扩展:
#!/bin/sh
echo “*.jpg”
echo ‘*.jpg’
这将打印”*.jpg” 两次。
单引号更严格一些。它可以防止任何变量扩展。双引号可以防止通配符扩展但允许变量扩展。
#!/bin/sh
echo $SHELL
echo “$SHELL”
echo ‘$SHELL’
运行结果为:
/bin/bash
/bin/bash
$SHELL
最后,还有一种防止这种扩展的方法,那就是使用转义字符——反斜杆:
echo *.jpg
echo $SHELL
这将输出:
*.jpg
$SHELL

Here documents

当要将几行文字传递给一个命令时,here documents(译者注:目前还没有见到过对该词适合的翻译)一种不错的方法。对每个脚本写一段帮助性的文字是很有用的,此时如果我们四有那个 here documents就不必用echo函数一行行输出。 一个 “Here document” 以 << 开头,后面接上一个字符串,这个字符串还必须出现在here document的末尾。下面是一个例子,在该例子中,我们对多个文件进行重命名,并且使用here documents打印帮助:
#!/bin/sh
# we have less than 3 arguments. Print the help text:
if [ $# -lt 3 ] ; then
cat <
ren — renames a number of files using sed regular expressions
USAGE: ren ‘regexp’ ‘replacement’ files…
EXAMPLE: rename all *.HTM files in *.html:
ren ‘HTM$’ ‘html’ *.HTM
HELP
exit 0
fi
OLD=”$1″
NEW=”$2″
# The shift command removes one argument from the list of
# command line arguments.
shift
shift
# $* contains now all the files:
for file in $*; do
if [ -f "$file" ] ; then
newfile=
echo “$file” | sed “s/${OLD}/${NEW}/g”
if [ -f "$newfile" ]; then
echo “ERROR: $newfile exists already”
else
echo “renaming $file to $newfile …”
mv “$file” “$newfile”
fi
fi
done
这是一个复杂一些的例子。让我们详细讨论一下。第一个if表达式判断输入命令行参数是否小于3个 (特殊变量$# 表示包含参数的个数) 。如果输入参数小于3个,则将帮助文字传递给cat命令,然后由cat命令将其打印在屏幕上。打印帮助文字后程序退出。 如果输入参数等于或大于3个,我们就将第一个参数赋值给变量OLD,第二个参数赋值给变量NEW。下一步,我们使用shift命令将第一个和第二个参数从 参数列表中删除,这样原来的第三个参数就成为参数列表$*的第一个参数。然后我们开始循环,命令行参数列表被一个接一个地被赋值给变量$file。接着我 们判断该文件是否存在,如果存在则通过sed命令搜索和替换来产生新的文件名。然后将反短斜线内命令结果赋值给newfile。这样我们就达到了我们的目 的:得到了旧文件名和新
文件名。然后使用mv命令进行重命名。

函数

如果您写了一些稍微复杂一些的程序,您就会发现在程序中可能在几个地方使用了相同的代码,并且您也会发现,如果我们使用了函数,会方便很多。一个函数是这个样子的:
functionname()
{
# inside the body $1 is the first argument given to the function
# $2 the second …
body
}
您需要在每个程序的开始对函数进行声明。
下面是一个叫做xtitlebar的脚本,使用这个脚本您可以改变终端窗口的名称。
这里使用了一个叫做help的函数。正如您可以看到的那样,这个定义的函数被使用了两次。
#!/bin/sh
# vim: set sw=4 ts=4 et:
help()
{
cat <
xtitlebar — change the name of an xterm, gnome-terminal or kde konsole
USAGE: xtitlebar [-h] “string_for_titelbar”
OPTIONS: -h help text
EXAMPLE: xtitlebar “cvs”
HELP
exit 0
}
# in case of error or if -h is given we call the function help:
[ -z "$1" ] && help
[ "$1" = "-h" ] && help
# send the escape sequence to change the xterm titelbar:
echo -e “33]0;$107″
#
在脚本中提供帮助是一种很好的编程习惯,这样方便其他用户(和您)使用和理解脚本。
命令行参数
我们已经见过$* 和 $1, $2 … $9 等特殊变量,这些特殊变量包含了用户从命令行输入的参数。迄今为止,我们仅仅了解了一些简单的命令行语法(比如一些强制性的参数和查看帮助的-h选项)。 但是在编写更复杂的程序时,您可能会发现您需要更多的自定义的选项。通常的惯例是在所有可选的参数之前加一个减号,后面再加上参数值 (比如文件名)。有好多方法可以实现对输入参数的分析,但是下面的使用case表达式的例子无遗是一个不错的方法。
#!/bin/sh
help()
{
cat <
This is a generic command line parser demo.
USAGE EXAMPLE: cmdparser -l hello -f — -somefile1 somefile2
HELP
exit 0
}
while [ -n "$1" ]; do
case $1 in
-h) help;shift 1;; # function help is called
-f) opt_f=1;shift 1;; # variable opt_f is set
-l) opt_l=$2;shift 2;; # -l takes an argument -> shift by 2
–) shift;break;; # end of options
-*) echo “error: no such option $1. -h for help”;exit 1;;
*) break;;
esac
done
echo “opt_f is $opt_f”
echo “opt_l is $opt_l”
echo “first arg is $1″
echo “2nd arg is $2″
您可以这样运行该脚本:
cmdparser -l hello -f — -somefile1 somefile2
返回的结果是:
opt_f is 1
opt_l is hello
first arg is -somefile1
2nd arg is somefile2
这个脚本是如何工作的呢?脚本首先在所有输入命令行参数中进行循环,将输入参数与case表达式进行比较,如果匹配则设置一个变量并且移除该参数。根据unix系统的惯例,首先输入的应该是包含减号的参数.

实例

现在我们来讨论编写一个脚本的一般步骤。任何优秀的脚本都应该具有帮助和输入参数。并且写一个伪脚本(framework.sh),该脚本包含了大多数脚本都需要的框架结构,是一个非常不错的主意。这时候,在写一个新的脚本时我们只需要执行一下copy命令:
cp framework.sh myscript
然后再插入自己的函数。
让我们再看两个例子:
二进制到十进制的转换
脚本 b2d 将二进制数 (比如 1101) 转换为相应的十进制数。这也是一个用expr命令进行数学运算的例子:
#!/bin/sh
# vim: set sw=4 ts=4 et:
help()
{
cat <
b2h — convert binary to decimal
USAGE: b2h [-h] binarynum
OPTIONS: -h help text
EXAMPLE: b2h 111010
will return 58
HELP
exit 0
}
error()
{
# print an error and exit
echo “$1″
exit 1
}
lastchar()
{
# return the last character of a string in $rval
if [ -z "$1" ]; then
# empty string
rval=”"
return
fi
# wc puts some space behind the output this is why we need sed:
numofchar=
echo -n “$1″ | wc -c | sed ‘s/ //g’
# now cut out the last char
rval=
echo -n “$1″ | cut -b $numofchar
}
chop()
{
# remove the last character in string and return it in $rval
if [ -z "$1" ]; then
# empty string
rval=”"
return
fi
# wc puts some space behind the output this is why we need sed:
numofchar=
echo -n “$1″ | wc -c | sed ‘s/ //g’
if [ "$numofchar" = "1" ]; then
# only one char in string
rval=”"
return
fi
numofcharminus1=
expr $numofchar “-” 1
# now cut all but the last char:
rval=
echo -n “$1″ | cut -b 0-${numofcharminus1}
}
while [ -n "$1" ]; do
case $1 in
-h) help;shift 1;; # function help is called
–) shift;break;; # end of options
-*) error “error: no such option $1. -h for help”;;
*) break;;
esac
done
# The main program
sum=0
weight=1
# one arg must be given:
[ -z "$1" ] && help
binnum=”$1″
binnumorig=”$1″
while [ -n "$binnum" ]; do
lastchar “$binnum”
if [ "$rval" = "1" ]; then
sum=
expr “$weight” “+” “$sum”
fi
# remove the last position in $binnum
chop “$binnum”
binnum=”$rval”
weight=
expr “$weight” “*” 2
done
echo “binary $binnumorig is decimal $sum”
该脚本使用的算法是利用十进制和二进制数权值 (1,2,4,8,16,..),比如二进制”10″可以这样转换成十进制:
0 * 1 + 1 * 2 = 2
为了得到单个的二进制数我们是用了lastchar 函数。该函数使用wc –c计算字符个数,然后使用cut命令取出末尾一个字符。Chop函数的功能则是移除最后一个字符。
文件循环程序
或许您是想将所有发出的邮件保存到一个文件中的人们中的一员,但是在过了几个月以后,这个文件可能会变得很大以至于使对该文件的访问速度变慢。下面的 脚本rotatefile可以解决这个问题。这个脚本可以重命名邮件保存文件(假设为outmail)为outmail.1,而对于outmail.1就变成了outmail.2 等等等等…
#!/bin/sh
# vim: set sw=4 ts=4 et:
ver=”0.1″
help()
{
cat <
rotatefile — rotate the file name
USAGE: rotatefile [-h] filename
OPTIONS: -h help text
EXAMPLE: rotatefile out
This will e.g rename out.2 to out.3, out.1 to out.2, out to out.1
and create an empty out-file
The max number is 10
version $ver
HELP
exit 0
}
error()
{
echo “$1″
exit 1
}
while [ -n "$1" ]; do
case $1 in
-h) help;shift 1;;
–) break;;
-*) echo “error: no such option $1. -h for help”;exit 1;;
*) break;;
esac
done
# input check:
if [ -z "$1" ] ; then
error “ERROR: you must specify a file, use -h for help”
fi
filen=”$1″
# rename any .1 , .2 etc file:
for n in 9 8 7 6 5 4 3 2 1; do
if [ -f "$filen.$n" ]; then
p=
expr $n + 1`
echo “mv $filen.$n $filen.$p”
mv $filen.$n $filen.$p
fi
done
# rename the original file:
if [ -f “$filen” ]; then
echo “mv $filen $filen.1″
mv $filen $filen.1
fi
echo touch $filen
touch $filen
这个脚本是如何工作的呢?在检测用户提供了一个文件名以后,我们进行一个9到1的循环。文件9被命名为10,文件8重命名为9等等。循环完成之后,我们将原始文件命名为文件1同时建立一个与原始文件同名的空文件。
调试
最简单的调试命令当然是使用echo命令。您可以使用echo在任何怀疑出错的地方打印任何变量值。这也是绝大多数的shell程序员要花费80%的时间来调试程序的原因。Shell程序的好处在于不需要重新编译,插入一个echo命令也不需要多少时间。
shell也有一个真实的调试模式。如果在脚本”strangescript” 中有错误,您可以这样来进行调试:
sh -x strangescript
这将执行该脚本并显示所有变量的值。
shell还有一个不需要执行脚本只是检查语法的模式。可以这样使用:
sh -n your_script
这将返回所有语法错误。

 

转载自:http://tech.49jie.com/?p=398

分类: shell 标签:

开源性能查看工具tsar使用

2013年5月21日 没有评论

简介

tsar是淘宝自己开发的一个采集工具,主要用来收集服务器的系统信息(如cpu,io,mem,tcp等),以及应用数据(如squid haproxy nginx等)。

收集到的数据存储在磁盘上,可以随时查询历史信息,输出方式灵活多样,另外支持将数据存储到mysql中,也可以将数据发送到nagios报警服务器。

tsar在展示数据时,可以指定模块,并且可以对多条信息的数据进行merge输出,带–live参数可以输出秒级的实时信息。

总体架构

Tsar是基于模块化设计的程序,程序有两部分组成:框架和模块。

框架程序源代码主要在src目录,而模块源代码主要在modules目录中。

框架提供对配置文件的解析,模块的加载,命令行参数的解析,应用模块的接口对模块原始数据的解析与输出。 模块提供接口给框架调用。

tsar依赖与cron每分钟执行采集数据,因此它需要系统安装并启用crond,安装后,tsar每分钟会执行tsar –cron来定时采集信息,并且记录到原始日志文件。

 

如何安装

从github上检出代码:

$git clone  git://github.com/kongjian/tsar.git

$cd tsar

$make

$make install

或者直接从github上下载源码

$wget -O tsar.zip  https://github.com/alibaba/tsar/archive/master.zip

$unzip tsar.zip

$cd tsar

$make

$make install

如何配置tsar

1.配置文件/etc/tsar/tsar.conf

debug_level 指定tsar的运行级别,主要用来调试使用

mod_xxx on/off 开启指定模块

out_interface 设置输出类型,支持file,nagios,db

out_stdio_mod 设置用户终端默认显示的模块

output_db_mod 设置哪些模块输出到数据库

output_db_addr 数据库的ip和端口

output_nagios_mod 设置哪些模块输出到nagios

include 支持include配置,主要用来加载用户的自定义模块

2.配置文件/etc/tsar/nagios.conf

这个文件主要是nagios服务器的配置

cycle_time 指定上报的间隔时间,由于tsar每一分钟采集一次,上报时会判断是否符合时间间隔,如设置300的话,则在0,5等整点分钟会上报nagios

threshold 设置某个要报警项的阀值,前面是模块和要监控的具体名称,后面的四个数据代表报警的范围,warn和critical的范围

3./etc/tsar/conf.d/*

这个目录下是用户的自定义模块配置文件

配置基本在用户开发自定义模块时确定,主要包含模块的开启,输出类型和报警范围

命令行使用

tsar命令行主要担负显示历史数据和实时数据的功能,因此有控制展示模块和格式化输出的参数,默认不带任何参数/选项的情况下,tsar打印汇总信息。

tsar命令行主要显示给人看的,所以数据展示中都进行了k/m/g等的进位。

tsar命令会在显示20行数据后再次打印各个列的列头,以利于用户理解数据的含义。

tsar的列头信息包括2行,第一行为模块名,第二行为列名。

tsar输出最后会作min/avg/max的汇总统计,统计所展示中的最小/平均/最大数据。

常用参数:

–help/-h 显示提示信息和模块信息

–live/-l 启用实时模式,类似iostat等,可以配合-i参数和模块参数使用。

–interval/-i 控制时间间隔,在打印历史数据中,单位是分钟,默认显示间隔5分钟;而实时模式(-l)下,单位是秒,默认是5秒。

–ndays/-n 控制显示多长时间的历史数据,默认1,单位天

–merge/-m 对有多个数据的展示,进行汇总,如机器上跑了3个squid,可以用 tsar –squid -m的放式进行展示汇总。

–cron 用于cron运行tsar采集功能。

常见用法列表:

tsar -i 1 -l 以1秒钟为间隔,实时打印tsar的概述数据

tsar 显示1天内的历史汇总(summury)信息,以默认5分钟为间隔
tsar –cpu -i 1 显示一天内cpu的历史信息,以1分钟为间隔
tsar –live –mem -i 2 以2秒钟为间隔,实时打印mem的数据。
tsar –cpu –mem -i 1 显示一天内的cpu和内存历史数据,以1分钟为间隔。

 

转载自:http://code.taobao.org/p/tsar/wiki/index/

分类: 开源软件 标签:

让后端tomcat日志获取真实的IP,而不是nginx 服务器的IP

2013年5月20日 2 条评论

今天有2个项目组的研发过来问我怎么设置tomcat日志显示真实ip,因为我们前面有个nginx反向代理,所有tomcat取到的是nginx的ip。需修改2个地方,nginx的配置文件和tomcat的server.xml

nginx nginx.conf中加

tomcat server.xml中加

当然你也可以diy日志文件里面的内容,顺序,打印项都可以调整。

测试结果:

 

分类: Tomcat 标签: ,

shell常用快捷键

2013年5月20日 没有评论

shell的常用快捷键,快捷键玩熟悉了在一定程度上是可以提高工作效率滴…

Ctrl + a 切换到命令行开始

Ctrl + e 切换到命令行末尾

Ctrl + l 清除屏幕内容

Ctrl + u 清除光标之前的内容

Ctrl + k 清除光标之后的内容

Ctrl + h 类似于退格键

Ctrl + r 在历史命令中查找 (这个非常好用,输入关键字就调出以前的命令了)

Ctrl + c 终止命令

Ctrl + d 退出shell

Ctrl + z 转入后台运行..

alt键比较少用,因为很多地方与远程登陆工具是有冲突的..

Alt + f 切换光标前的字母

Alt + b 切换光标后的字母

上个linux命令的后面部分 ” !$ ”

 

分类: shell 标签:

Centos 6.x 部署puppet

2013年5月17日 没有评论

概述

puppet 是一种 Linux、Unix 平台的集中配置管理系统,使用自有的 puppet 描述语言,可管理配置文件、用户、cron 任务、软件包、系统服务等。puppet 把这些系统实体称之为资源,puppet 的设计目标是简化对这些资源的管理以及妥善处理资源间的依赖关系。
puppet 采用 C/S 星状的结构,所有的客户端和一个或几个服务器交互。每个客户端周期的(默认半个小时)向服务器发送请求,获得其最新的配置信息,保证和该配置信息同步。每个 puppet 客户端每半小时(可以设置 runinterval=30)连接一次服务器端, 下载最新的配置文件,并且严格按照配置文件来配置服务器. 配置完成以后,puppet 客户端可以反馈给服务器端一个消息. 如果出错,也会给服务器端反馈一个消息

原理

Puppet 后台运行的时候默认是半小时执行一次,不是很方便修改。可以考虑不让它在后台跑而是使用 crontab 来调用。这样可以精确控制每台客户端的执行时间。分散执行时间也可以减轻压力
Puppet 的工作细节分成如下几个步骤:
1、 客户端 puppetd 调用 facter,facter 会探测出这台主机的一些变量如主机名、内存大小、IP 地址等。然后 puppetd 把这些信息发送到服务器端。
2、 服务器端的 puppetmaster 检测到客户端的主机名,然后会到 manifest 里面对应的 node 配置,然后对这段内容进行解析,facter 送过来的信息可以作为变量进行处理的,node 牵涉到的代码才解析,其它的代码不不解析,解析分几个过程:语法检查、然后会生成一个中间的伪代码,然后再把伪代码发给客户机。
3、 客户端接收到伪代码之后就会执行,客户端再把执行结果发送给服务器。
4、 服务器再把客户端的执行结果写入日志

安装前准备

 环境介绍

 NTP配置

由于我是在公司内部openstack平台生产的虚拟机,默认有了时间同步,没有的话加个crontab。

关闭iptables

 FQDN设置

hosts绑定,或者有dns更好,生产环境下最好还是用dns进行域名解析。

 新版本命令变更

Puppet 3.01,对很多以前版本的命令已经去掉

                  

我安装的时候用的puppet3.1,也要使用新版命令

ruby安装

Puppet 需要 Ruby 的支持,如果要查看命令行帮助的话需要额外 ruby-rdoc 这个软件包:

安装puppet服务端

如果系统是centos 5 系列的话,注意更改源地址,服务端配置文件不用修改。

puppet客户端安装

软件安装

Puppet 需要 Ruby 的支持,如果要查看命令行帮助的话需要额外 ruby-rdoc 这个软件包:,安装后需修改一处配置文件。

配置文件修改

 启动服务

 

证书申请

客户端发起证书请求

Puppet客户端与服务器端是通过SSL隧道通信的,客户端安装完成后,需要向服务器端申请证书:
首次连接服务器端会发起证书申请,在客户端执行命令如下:

如果返回以下信息说明证书请求成功了

服务端查看证书请求

在puppet服务器端查看到申请证书的客户端主机名。

注:前面有+号的说明已经授权签发了。

服务端颁发证书

查看是否颁发成功

验证puppet配置

在服务端写个例子测试一下。这个例子作用很简单,用来在客户端的/tmp目录下新建一个 woyoo.txt 文件,内容为:hello,puppet!在服务端/etc/puppet/manifests下编写代码:【服务器端不需要新建这个文件】

在客户端上执行 puppet,运行成功后会在 /tmp 看到新生成的 test.txt:

文件同步

服务端编写文件同步脚本

客户端同步策略

案例详解

Host文件同步

当我们服务器数量有几百台的时候,这样一个个加node肯定是不行了,我们采用模块化来实现

创建目录

创建所须文件

nodes.pp中使用了正则表达式,这使得一个非常 简单的node可以匹配多个客户端,而对于特殊主机来讲,可单独在文件结尾添加node即可

通过一个if/elsif决断语句,结合Puppet内置变量$operatingsystem可同步任何跨平台的操作系统的hosts文件

客户端请求策略后的结果

 用户管理

创建账户

我想批量创建个www账号

modules下创建相应的目录

注意:

客户端请求策略

 删除账号

比较懒,就在刚刚那个创建用户的脚本里面改了下。

客户端请求策略

 crontab

创建相应的目录和脚本

引用模块

 

客户端请求策略

 Puppet Dashboard

mysql安装

优化mysql设置

编辑 /etc/my.cnf, 在[mysqld]字段,增加最后一行.

启动服务

设置密码并创建数据库

 Passenger+Apache+Dashboard

让Apache支持ruby

配置Dashboard

编辑 /usr/share/puppet-dashboard/config/database.yml

初始化数据库

 

配置Apache

我们需要整合Passenger和apache

重启服务

配置puppet

让Dashboard使用Reports,现在默认agent是已经启用Report的功能,所以你就不需要设置agent,你只需要设置Server端就可以.

重启puppetmaster 服务

访问 http://puppet.54im.com

导入报告

 Delayed Job Workers

查看启动的job

停止delay job

Dashbaord里现在可以看到数据了

分类: puppet, 自动化运维 标签: