秀才


  • Home

  • About

  • Tags

  • Archives

  • Search

拼接新的变量名

Posted on 2018-10-16 | Visitors:

##shell变量作为另一个变量名

使用eval

1
2
3
#!/bin/sh
i=1
eval echo '$'rediscache$i

例1:

1
2
3
dev@pirate-test:~chimps (master *%) $ i=1                                                                                                              
dev@pirate-test:~chimps (master *%) $ eval echo '$'rediscache$i
10.100.100.100

例2

1
2
3
4
5
6
7
#!/bin/sh

for ((i = 1; i < 60; i++)); do
redis=$(eval echo '$'rediscache$i)
count=$(redis-cli -h $redis -a ***** DEL key1)
echo {idx:,$i,redis:,$redis,count:,$count}
done

优秀一点点

Posted on 2018-10-11 | Visitors:

在社会学领域,所谓成功就是“优势积累”的结果。

职业冰球队员一开始只比最初所在球队的队友好一点点,然而这微小的优势带来的机遇,扩大了他和那些队友之间的差距,随后差距与机会交替发挥作用,微小的差距被越拉越大——最终被选中的队员成了真正出众的天才。

由此可以看出,天才并非一开始就表现出众,一开始他只是比别人优秀那么一点点。

承认病态的自我

Posted on 2018-10-11 | Visitors:

承认病态的自我需要勇气,佛教有一句名言:海无边,回头是岸

圣人改变的是自己,走的是一条修行的路。通过完善自己,可以感召别人,唤醒别人的良知,给别人指引。

与之相反,由于大恶之人害怕改变自己,所以便去改变别人,他们不择手段去控制别人,压制别人,甚至毁灭别人的生命。

放弃自由

Posted on 2018-10-11 | Visitors:

今天读的一章为:过分依赖集体,个人的心智就会退化

推理很到位:

“自然赋予人自由意志,也就是赋予了人自主选择的权利。人生是有一个接一个的选择组成的,不同的选择导致不同的人生。但是不可否认的是,伴随着自主选择,人也就多了更多的烦恼和痛苦。选择是一件令人烦恼和痛苦的事情。首先选择意味着放弃。选择一条路,意味着放弃其他的路;有了一个选择,意味着要放弃其他选择。由于人们不愿意放弃,所以每当面临选择时,内心总是充满烦恼和痛苦。其次,选择会产生结果,人们必须为自己的选择负责,并承受选择所带来的结果。当然,好的结果令人欣喜,但坏的结果不仅会招致别人的指责、埋怨,也会让自己陷入懊恼和自责之中,令人痛苦不堪。许多人不愿意承受选择所带来的痛苦,便会把自主选择的权利拱手让给他人。这就是弗洛姆所说的逃避自由。

逃避自由的人放弃了自主选择的权利,也就放弃了独立思考的能力,这意味着他们将失去独立的自我,失去自己的灵魂。一个没有灵魂的人就像一张破碎的纸片,盲目地追随着每一阵风,完全失去了掌控自我的能力,最终会成为魔鬼撒旦的工具,干出许多邪恶的事情。”

我感觉说的很对,想想和以前和朋友一块儿的时候,有什么事情都是让对方做选择,虽然会让别人会觉得你随和,为他人着想。实际上是自己太多胆小,不敢承担选择所带来的风险。是因为怕,才放弃了自主思考的权利,给人一种没有底气,没有底线的感觉。

人性的弱点摘录

Posted on 2018-10-11 | Visitors:

在与人相处时,要切记:与我们交往的不是纯粹按道理或逻辑生活的人,而是充满了感情的,带有偏见、傲慢和虚荣的人。

定时任务

Posted on 2018-10-09 | Visitors:

基本规则

1
2
3
4
5
6
7
8
minute   hour   day   month   week   command

- minute: 表示分钟,可以是从0到59之间的任何整数。
- hour:表示小时,可以是从0到23之间的任何整数。
- day:表示日期,可以是从1到31之间的任何整数。
- month:表示月份,可以是从1到12之间的任何整数。
- week:表示星期几,可以是从0到7之间的任何整数,这里的0或7代表星期日。
- command:要执行的命令,可以是系统命令,也可以是自己编写的脚本文件。

特殊字符

1
2
3
4
星号(*):代表所有可能的值,例如month字段如果是星号,则表示在满足其它字段的制约条件后每月都执行该命令操作。
逗号(,):可以用逗号隔开的值指定一个列表范围,例如,“1,2,5,7,8,9”
中杠(-):可以用整数之间的中杠表示一个整数范围,例如“2-6”表示“2,3,4,5,6”
正斜线(/):可以用正斜线指定时间的间隔频率,例如“0-23/2”表示每两小时执行一次。同时正斜线可以和星号一起使用,例如*/10,如果用在minute字段,表示每十分钟执行一次。

编辑定时任务

1
2
crontab  -e
* * * * * 命令

查看系统定时任务

1
crontab  -l

删除定时任务

1
crontab  -r

服务管理

/sbin/service crond start //启动服务
/sbin/service crond stop //关闭服务
/sbin/service crond restart //重启服务
/sbin/service crond reload //重新载入配置

例子

每1分钟执行一次command

1
* * * * * command

每小时的第3和第15分钟执行

1
3,15 * * * * command

在上午8点到11点的第3和第15分钟执行

1
3,15 8-11 * * * command

每隔两天的上午8点到11点的第3和第15分钟执行

1
3,15 8-11 */2 * * command

每个星期一的上午8点到11点的第3和第15分钟执行

1
3,15 8-11 * * 1 command

每晚的21:30重启smb

1
30 21 * * * /etc/init.d/smb restart

每月1、10、22日的4 : 45重启smb

1
45 4 1,10,22 * * /etc/init.d/smb restart

每周六、周日的1:10重启smb

1
10 1 * * 6,0 /etc/init.d/smb restart

每天18 : 00至23 : 00之间每隔30分钟重启smb

1
0,30 18-23 * * * /etc/init.d/smb restart

每星期六的晚上11:00 pm重启smb

1
0 23 * * 6 /etc/init.d/smb restart

每一小时重启smb

1
* */1 * * * /etc/init.d/smb restart

晚上11点到早上7点之间,每隔一小时重启smb

1
* 23-7/1 * * * /etc/init.d/smb restart

每月的4号与每周一到周三的11点重启smb

1
0 11 4 * mon-wed /etc/init.d/smb restart

一月一号的4点重启smb

1
0 4 1 jan * /etc/init.d/smb restart

MySQL max_allowed_packet设置

Posted on 2018-10-08 | Visitors:

什么是max_allowed_packet

max_allowed_packet是mysql允许插入一条数据的大小

查看目前配置

1
2
3
4
5
6
7
8
mysql> show VARIABLES like '%max_allowed_packet%';
+--------------------------+------------+
| Variable_name | Value |
+--------------------------+------------+
| max_allowed_packet | 16777216 |
| slave_max_allowed_packet | 1073741824 |
+--------------------------+------------+
2 rows in set (0.01 sec)

修改方法

  1. 编辑my.cnf文件

    1
    max_allowed_packet=20M

    保存重启mysql

    如果找不到my.cnf,可以通过命令:mysql --help | grep my.cnf

  2. 在mysql 命令行中运行

    1
    set global max_allowed_packet = 2*1024*1024*10

    然后关闭掉这此mysql server链接,再进入

net-http

Posted on 2018-10-08 | Visitors:

上传

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// 获取form文件
file, err := c.FormFile("attachment")
if err != nil {
return nil, GenError(err)
}
now := time.Now()
// 检查目录
dir := fmt.Sprintf("upload/%d%d", now.Year(), now.Month())
if !utils.Exists(dir) {
err = os.MkdirAll(dir, os.ModePerm)
if err != nil {
return nil, GenError(err)
}
}
// 创建文件
path := fmt.Sprintf("%s/%d%s", dir, now.Unix()%(3600*24*30), file.Filename)
out, err := os.Create(path)
if err != nil {
return nil, GenError(err)
}
f, err := file.Open()
if err != nil {
return nil, GenError(err)
}
_, err = io.Copy(out, f)
if err != nil {
return nil, GenError(err)
}

下载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
file, err := os.Open(attachment.Path)
if err != nil {
OnError(c, err)
return
}
defer file.Close()

// 读取文件头信息
fileHeader := make([]byte, 512)
file.Read(fileHeader)
fileContentType := http.DetectContentType(fileHeader)
fileStat, _ := file.Stat()
fileSize := strconv.FormatInt(fileStat.Size(), 10)

// 设置response header头,gin框架也可以用c.Header("","")
c.Writer.Header().Set("Content-Disposition", "attachment; filename="+attachment.Name)
c.Writer.Header().Set("Content-Type", fileContentType)
c.Writer.Header().Set("Content-Length", fileSize)

// 注意还原io读取指针
file.Seek(0, 0)
_, err = io.Copy(c.Writer, file)
if err != nil {
OnError(c, err)
return
}

通过默认的net/http服务

1
2
3
4
5
6
7
8
9
10
11
12
13
func main() {
http.HandleFunc("/", HelloWorld)
errpr := http.ListenAndServe(":8080", nil)
if errpr != nil {
log.Fatal("listen falded")
}
}

// 由于http.ResponseWriter只是一个接口,所以不需要引用传值
// 而http.Request是一个数据(结构类型),所以需要引用传值
func HelloWorld(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, "hello world")
}

重写ServeHTTP方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
type MyHandler struct {}
func main() {
mux := http.NewServeMux()
mux.Handle("/", &MyHandler{})
mux.HandleFunc("/home", Home)
err := http.ListenAndServe(":8080", mux)
if err != nil {
log.Fatal("listen falded")
}
}

func (this *MyHandler)ServeHTTP(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, "hello world " + r.URL.Path)
}

func Home(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, "home " + r.URL.Path)
}

重写http.Server

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// 定义全局变量
var mux map[string]func(http.ResponseWriter, *http.Request)
type MyHandler struct{}

func main() {
server := http.Server{
Addr: ":8080",
// 定义server的默认handler
Handler: &MyHandler{},
ReadTimeout: 2 * time.Second,
}
// 对全局变量赋值
mux = make(map[string]func(http.ResponseWriter, *http.Request))
mux["/home"] = Home
mux["/user"] = User
err := server.ListenAndServe()
if err != nil {
log.Fatal("listen faild")
}

}
// handler默认执行的方法
func (*MyHandler)ServeHTTP(w http.ResponseWriter, r *http.Request) {
// 根据map转发路由
if v, ok := mux[r.URL.String()]; ok {
v(w, r)
return
}
io.WriteString(w, "hello world " + r.URL.Path)
}

func Home(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, "home " + r.URL.Path)
}

func User(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, "user " + r.URL.Path)
}

原生中间件编写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
package main

import (
"net/http"
"fmt"
)

type SingleMiddle struct {
handler http.Handler
allowHost []string
}

type myHandler struct{}

func main() {
var allowHosts []string
allowHosts = append(allowHosts, "localhost:8080")
MyHandler := &myHandler{}
singleHost := NewSingle(MyHandler, allowHosts)
http.ListenAndServe(":8080", singleHost)
}

// middleware
func NewSingle(handler http.Handler, allowHost []string) (*SingleMiddle) {
return &SingleMiddle{handler, allowHost}
}
// middleware
func (s *SingleMiddle) ServeHTTP(w http.ResponseWriter, r *http.Request) {
host := r.Host
isIn := false
fmt.Println(s.allowHost)
fmt.Println(host)
for _, allowH := range s.allowHost {
if allowH == host {
isIn = true
}
}
if isIn {
s.handler.ServeHTTP(w, r)
} else {
w.WriteHeader(403)
}
}
// custom handler
func (m *myHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(200)
w.Write([]byte("helle golang"))
}

文摘

Posted on 2018-09-28 | Visitors:

做人难

“ 海浪卷走了小孩的鞋子,小孩在海滩上写下:大海是小偷!一个男人在海里打捞出了一些好东西,在沙滩上写到:大海真慷慨! 一少年溺水身亡,他的母亲在海边写了:大海是凶手! 一个老翁打捞到了珍珠,他写到:大海真仁慈! …这时一个海浪冲上来抹去了所有的字, 大海平静地说:如果你想成为大海, 就不要在意别人对你的评说! 因为你做不到让所有人满意。人生如果容易的话,你当初来到这个世界时就不会从哭泣开始! ” 共勉

喜欢

有一个民谣青年曾说:最单纯的喜欢就是,就算你拒绝了我,我对你也永远没有埋怨。但我不会再靠近了。如果你有求于我,我依然会鞠躬尽瘁。从今往后我会把喜欢藏起来,不再招摇过市了,我会努力过得好,希望你也是。

awk

Posted on 2018-09-25 | Visitors:

参见linux手册awk部分

示例文本

test.txt

1
2
3
4
5
6
Beth	4.00	0
Dan 3.75 0
kathy 4.00 10a
Mark 5.00 20
Mary 5.50 22
Susie 4.25 18

基本语法示例

awk '$3 >0 { print $1, $2 * $3 }' emp.data

通过awk脚本文件

test.awk

1
2
3
/.+th/ {
print $0
}

运行脚本:

1
2
3
4
$ awk -f test.awk test.txt
# 结果:
Beth 4.00 0
kathy 4.00 10

BEGIN与END

1
2
3
4
5
6
7
8
9
BEGIN{
print "begin search"
}
END{
print "all end"
}
/.+th/{
print $0
}

运行:

1
2
3
4
5
6
$ awk -f test.awk test.txt
# 结果
begin search
Beth 4.00 0
kathy 4.00 10
all end

内置变量

ARGC

表示在命令中提供的参数的个数
例:

1
awk 'BEGIN {print "Arguments =", ARGC}' One Two Three Four

结果:Arguments = 5

ARGV

这个变量表示存储命令行输入参数的数组,数组的有效索引是从 0 到 ARGC-1
例

1
2
3
4
5
6
7
8
9
10
11
BEGIN{
for (i = 0; i < ARGC ;i++){
printf "ARGV[%d]=%s\n", i, ARGV[i]
}
}
END{
print "all end"
}
/.+th/{
print $0
}

运行:

1
2
3
4
5
6
7
$ awk -f test.awk test.txt
# 结果
ARGV[0]=awk
ARGV[1]=test.txt
Beth 4.00 0
kathy 4.00 10
all end

ENVISON环境变量

1
2
3
4
5
BEGIN{
for (n in ENVIRON){
print n ": " ENVIRON[n]
}
}

运行:

1
2
3
4
5
6
7
8
$ awk -f test.awk test.txt
# 结果
GOROOT: /usr/local/Cellar/go/1.7.4_1/libexec
LESS: -R
PAGER: less
AWKPATH: .:/usr/local/Cellar/gawk/4.1.4_1/share/awk
OLDPWD: ...
TERM_PROGRAM: iTerm.app

FILENAME

文件名

1
2
3
4
5
6
BEGIN{
print FILENAME
}
END{
print FILENAME
}

运行:

1
2
3
/chimps/linux/awk awk -f test.awk test.txt

test.txt

可以看出在begin的时候FILENAME变量为空值

FS

此变量表示输入的数据域之间的分隔符,其默认值是空格。 你可以使用 -F 命令行选项改变它的默认值。

NF

此变量表示当前输入记录中域的数量
test.txt

1
2
3
4
Marks
Mark 5.00
Mary 5.50 22
Susie 4.25 18

test.awk

1
2
3
NF>2{
print $0
}

执行:

1
2
3
/chimps/linux/awk awk -f test.awk test.txt
Mary 5.50 22
Susie 4.25 18

NR(FNR)

默认的就是读取的数据行数,NR可以理解为Number of Record的缩写,FNR则为File Number of Record

1
2
3
4
5
6
7
8
9
10
11
# class1:
zhaoyun 85 87
guanyu 87 88
liubei 90 86
# class2:
caocao 92 87 90
guojia 99 96 92
# test.awk:
{
print NR,FNR,$0
}

执行:

1
2
3
4
5
6
/chimps/linux/awk awk -f test.awk class1 class2
1 1 zhaoyun 85 87
2 2 guanyu 87 88
3 3 liubei 90 86
4 1 caocao 92 87 90
5 2 guojia 99 96 92

数组操作

1
2
3
4
5
6
7
8
9
BEGIN{
arr[1] = "zhangsan"
arr["lisi"] = "lisi"
arr[2] = "wangwu"

for (n in arr){
print arr[n]
}
}

运行:

1
2
3
4
/chimps/linux/awk awk -f test.awk test.txt
lisi
zhangsan
wangwu

判断数组中是否存在某一项

1
2
3
4
5
6
7
8
9
10
11
12
13
14
BEGIN{
arr["zhangsan"] = "wangwu"
if("zhangsan" in arr){
print "zhangsan ok"
}else{
print "zhangsan not found"
}

if("lisi" in arr){
print "lisi ok"
}else{
print "lisi not found"
}
}

运行:

1
2
3
/chimps/linux/awk awk -f deal_err.awk
zhangsan ok
lisi not found

DEMO

获取每个进程的内存占用

test.awk:

1
2
3
4
5
6
7
8
9
NR != 1 && $4 > 0{
mem[$4] = $11
}
END{
asorti(mem, Nmem)
for (k in Nmem){
print mem[Nmem[k]], Nmem[k]
}
}

运行:
ps aux | awk -f test.awk

多行日志处理

file.log:

1
2
3
4
5
6
7
8
[2017-02-17 16:19:04] [285]
<- /v2/api/file/item/476
-> {"success":true,"successInfo":{}}

[2017-03-10 11:57:42] []
<- /v2/api/file/diff?fid1=381&fid2=287
-> {"success":false,"errorInfo":"长度不能为空","successInfo":{},"debug":{"line":37,"info":null}}
...

方式一:使用数组

deal_err.awk

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
BEGIN{
sub_index = 0
}
/^\[/{
arr_line[sub_index] = $1 "\t" $2
}

/^<-/{
arr_line[sub_index] = arr_line[sub_index] "\t" $2
}

/^->/{
text = substr($2, 2, length($2)-2)
split(text, text_arr, ",")
split(text_arr[1], text_arr1, ":")
if (text_arr1[2] == "false"){
arr[sub_index] = arr_line[sub_index] "\t" text_arr[2]
sub_index ++
}
}

END{
for (k in arr) {
print k,arr[k] >> "output.txt"
}
}

运行:

1
awk -f deal_err.awk file.log

方式二:匹配成功就写到文件

deal_err.awk

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/^\[/{
url = $1 "\t" $2
}

/^<-/{
request = arr_line[sub_index] "\t" $2
}

/^->/{
response = substr($2, 2, length($2)-2)
split(response, res_arr, ",")
split(res_arr[1], res_arr1, ":")
if (res_arr1[2] == "false"){
print url,request,res_arr[2] > "output.txt"
}
}

很明显,这样可读性好一些
运行:

1
awk -f deal_err.awk file.log

1234…7

chimps

63 posts
32 tags
RSS
© 京ICP备19001740号-1 2020 chimps
Powered by Hexo
|
Theme — NexT.Gemini v5.1.4