| Yang |


  • Home

  • Tags

  • Archives

Python理解yiled关键字

Posted on 2019-08-07

一直对Python的yield关键字有点迷糊,今天整理下相关的知识。

迭代的概念

Python是一门极其灵活的语言,其很多数据里都包含了其他类型的元素。而我们在实际使用的时候,经常需要逐个地取出元素。逐个获取元素的过程,就是迭代。

Python的 list,tuple,string等顺序类型,还包括 dict,set等也都是。就是如果我们可以从一个对象中,逐个地获取元素,那么这个对象是「可迭代的」。

至于迭代器则是抽象的一个数据流,是只允许迭代一次的对象。

1
2
for i in range(10):
print(i)

生成器和yield关键字

生成器函数是一种特殊的函数,而生成器则是特殊的迭代器。

1
2
3
4
5
6
7
8
9
10
11
def func():
return 1

def gen():
yield 1

print(type(func)) # <class 'function'>
print(type(gen)) # <class 'function'>

print(type(func())) # <class 'int'>
print(type(gen())) # <class 'generator'>

最重要的差异是二者返回的类型是不一样的,生成器函数返回一个迭代器。

yield

yield关键字仅用户定义生成器函数。与普通函数不同的是,生成器函数是惰性计算的,只有在返回的生成器调用成员方法时,相应函数中的代码才会被执行。

1
2
3
4
5
6
def square():
for x in range(4):
yield x ** 2
square_gen = square()
for x in square_gen:
print(x)

由前面可知,square_gen表示一个迭代器对象,for 循环会调用迭代器对象的 next() 函数,将生成器中的下一个值赋值给 x , 然后再继续循环,直到终止。

yield的好处

节省时间空间上的开销。Python 之所以要提供这样的解决方案,是因为在很多时候,我们只是需要逐个顺序访问容器内的元素。大多数时候,我们不需要一口气获取容器内所有的元素。

实战一下

生成斐波那契数列

1
2
3
4
5
6
7
8
def gen_fib(n_max):
n,a,b = 0,0,1
while n < n_max:
yield b
a , b = b , a+b
n += 1
fib = [x for x in gen_fib(10)]
fib # [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

参考

  1. Python 中的黑暗角落(一):理解 yield 关键字
  2. 廖雪峰的官方网站

感恩 始终 这位大佬,跟着走一遍打了一遍!

Python模块hashlib

Posted on 2019-08-05

简介

Python内置的hashlib模块提供了我们常见的摘要算法,例如 md5 , sha256 等。

那什么是摘要算法呢?摘要算法又称哈希算法、散列算法。它通过一个函数 f(),把任意长度的数据 data 转换为一个长度固定的数据串 digest (通常用16进制的字符串表示)。同时我们的函数 f() 也是一个单向函数(反推及其困难),所以我们可以用摘要算法来查看数据是否被篡改过。

我日常工作中则是用来对人群包所需要的PHONE/IMEI/IDFA等信息加密。

使用

方法及属性简介
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

import hashlib

# 可以运行在Python解释器中的哈希算法名称的集合
hashlib.algorithms_available

# 保证在所有平台上此模块支持的哈希算法名称的集合
hashlib.algorithms_guaranteed

# 创建哈希对象
hashlib.md5() # and so on

# 将字节对象填充到hash对象中

hashlib.update()

# 返回二进制加密结果
hashlib.digest()

# 返回十六进制加密解决
hashlib.hexdigest()
动手实现一下

对一个文件的第二行使用md5()进行加密:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/usr/bin/env python  
#coding:utf-8
import csv
import hashlib
with open('user_md5.csv', 'w', newline='') as f:
csvwriter = csv.writer(f)
csvwriter.writerow(['md5'])
csvreader=open('userid.csv','r')
for line in csvreader:
data=[]
m=hashlib.md5()
m.update(line.strip().split(',')[1].encode('utf-8'))
encodeStr=m.hexdigest()
data.append(encodeStr)
csvwriter.writerow(data)
要加点盐

这个加密也不是绝对安全的,破解方式可以是碰撞。假设密码是生日,那我完全可以不用去逆向计算,我暴力计算现有的所有的生日经过摘要算法处理之后的值,然后去匹配即可。所以解决方法可以是加点 salt 。

具体实现还是很简单的,夜深了,先去休息。

参考

  1. Python3中的hashlib模块
  2. 廖雪峰的官方网站-hashlib
  3. Python模块简介 — hashlib

Seaborn中文乱码问题解决

Posted on 2019-08-01

试了好多方法,亲测这个Mac+Anaconda下有效。

1
2
3
4
5
6
7
8
9
10
11
12
13
import seaborn as sns 
import matplotlib.pyplot as plt
import pandas as pd

%matplotlib inline

import matplotlib.pyplot as plt
import seaborn as sns

plt.rcParams['font.family'] = ['Arial Unicode MS'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False #用来正常显示负号

sns.set_style('whitegrid',{'font.sans-serif':['Arial Unicode MS','Arial']})

浅识RSA算法

Posted on 2019-07-26

RSA的历史

RSA加密算法是一种非对称加密算法,在互联网领域里被广泛使用。RSA是1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的。当时他们三人都在麻省理工学院工作。RSA就是他们三人姓氏开头字母拼在一起组成的。

RSA的具体原理

RSA主要利用了极大整数的因数分解的难度来保证算法的可靠性。

产生公钥和私钥
  1. 随便选择两个大的质数$p$和$q$,计算$N=p \cdot q$
  2. 利用欧拉函数,求得$r=\varphi((N)=\varphi((p) \cdot \varphi((q) = (p-1) \cdot (q-1) $
  3. 选择一个数$e$,满足$1 < e < r$且$e$与$r$互质,取$e$关于$d$的模逆元$d$,满足$ed \equiv {1 \bmod {r}}$
  4. 销毁$p$和$p$

现在$(N,e)$是公钥,$(N,d)$是私钥。

加密消息

假设Alice想要给Bob发送一条信息$m$,那么Alice有两步需要做:

  • 把$m$按照一定规则转化成非负整数$n$,如果太长可以分几段加密
  • 将$n$加密为$c$

然后就可以把$c$发送给Bob了。

解密消息

Bob接受到消息之后,就可以利用密钥$d$来解码

取到$n$之后,就可以按照约定的$m$转换成$n$的规则,倒回去得到$m$。

相关数学知识
  • 质数
  • 欧拉函数
  • 拓展欧几里得算法
  • 模逆元

RSA的简单实现

1
2
3
4
5
6
7
8
###朴素欧几里得算法

def gcb(a,b):
if b == 0 :
return a
else:
print(b,a%b)
return gcb(b , a%b)
1
2
3
4
5
6
7
8
9
10
### 拓展欧几里得算法
### 根据1所述,设a,b的最大公约数为gcd(a,b),则存在整数x,y使得gcd(a,b)=ax+by。扩展欧几里得则是用来求出这个x,y的,并且同时可以求出a,b的最大公约数
### $$ \begin{cases} x_1=y_2 \\ y_1=x_2-(n/m) \cdot y_2 \end{cases} $$

def ex_gcb(a,b):
if b == 0:
return 1,0
else:
x,y = ex_gcb(b,a%b)
return y,(x-(a//b)*y)
1
ex_gcb(43,23)
(-8, 15)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
###  蒙哥马利幂模运算
### (a*b)%n = (a%n*b%n)%n

#整数转化为二进制
def int2Bin(n):
binlist=[]
while n!=0:
binlist.append(n%2)
n >>= 1
return binlist

# 蒙哥马利幂模运算 a^d%n
def modExp(a,d,n):
binlist = int2bin(d)
res = 1
for i in binlist:
if i :
res = ( res * a ) % n
a = ( a * a ) % n
return res


modExp(2,16,7)
2
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
49
50
51
52
# 检测大整数是否是素数,如果是素数,就返回True,否则返回False
# 来自网上大佬的代码
# 素数生成逻辑 还是有点问题

import random
def rabin_miller(num):
s = num - 1
t = 0
while s % 2 == 0:
s = s // 2
t += 1

for trials in range(5):
a = random.randrange(2, num - 1)
v = pow(a, s, num)
if v != 1:
i = 0
while v != (num - 1):
if i == t - 1:
return False
else:
i = i + 1
v = (v ** 2) % num
return True


def is_prime(num):
# 排除0,1和负数
if num < 2:
return False

# 创建小素数的列表,可以大幅加快速度
# 如果是小素数,那么直接返回true
small_primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997]
if num in small_primes:
return True

# 如果大数是这些小素数的倍数,那么就是合数,返回false
for prime in small_primes:
if num % prime == 0:
return False

# 如果这样没有分辨出来,就一定是大整数,那么就调用rabin算法
return rabin_miller(num)


# 得到大整数,默认位数为1024
def get_prime(key_size=1024):
while True:
num = random.randrange(2**(key_size-1), 2**key_size)
if is_prime(num):
return num
1
get_prime(1024)
162678631691829774667522629535073160955825399182602693661545242792106676238539472548234877060876228787484523858207867783251387491999600134388980090439045215608645863076210778718260527620108430686424624076200773582708629154239529895125774945352642184329001660453968578704168280059308704550631900163173081902239
1
2
3
4
5
6
7
8
9
10
11
12
13
def gen_key(p,q):
N = p * q # 计算N
r = (p-1) * (q-1) # 计算r
e = 65537 # 取e
d,x = ex_gcb(e,r) ### ed \equiv { 1 \pmod r} -> ed + yn = 1 ,类似于扩展欧几里得形式
d = abs(d)
return e,d,N

def encrypt(m,N,e):
return modExp(m,e,N)

def decrypt(c,N,d):
return modExp(c,d,N)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
## 测试整体过程

p,q = get_prime(1024),get_prime(1024)
m = 1995101219950817
e,d,N = gen_key(p,q)

enc = encrypt(m,N,e)
res = decrypt(enc,N,d)

if res == m :
print('解密成功')
print('密文是%d'%(enc))
print('明文是%d'%(res))
else:
print('加密失败')
解密成功
密文是14005144118830483850652822657072015923931651283373191007705567320344608498783170654858772312139590781517022245572740058228425238815700795267975461803686242362890194249947123896021635220125683107528036663909234677369590244069330529163467280287893994970335492795549817696086606381221855273000994999391165045098621373956100419478927732414261552853418860553749988881775967955441571219829233196014735356284125413142119509579602440902130879271195998880056144148006467107689489924816408971514890284627704928072054400838999570987152631984324906697106158618432179795774465341559150912656124918370457081515488677503660447595363
明文是1995101219950817

参考

  • RSA算法
  • 欧几里得算法求模反元素
  • 加密和RSA算法

Linux下统计文件夹里的文件数目

Posted on 2019-07-26

有时候我们不仅仅要看文件的大小,还需要统计下文件夹里文件数目,这里记录一下。

我们可以使用ls、grep、wc这三个常用的命名来组合统计出我们想要的信息

  1. 统计文件夹中的文件(不包括子目录)

    1
    $ls -l | grep '^-' | wc -l
  2. 统计文件夹中的文件(包括子目录)

    1
    $ls -lR | grep '^-' | wc -l
  3. 统计文件夹中的目录(包括子目录)

    1
    $ls -lR | grep '^d' | wc -l

命令解析

  • ls : ls -l长列表输出该目录下文件信息(注意这里的文件是指目录、链接、设备文件等),每一行对应一个文件或目录,ls -lR是列出所有文件,包括子目录。
  • grep : grep '^-'表示只保留一般文件,grep '^d'表示只保留目录
  • wc : wc -l统计过滤之后的文件行数

参考:SnailTyan的博客

2019观影记录

Posted on 2019-07-19

《流浪地球》

9分

虽然剧情,台词之类的有点尴尬,但是特效牛逼,情怀满分,诚意满满呀,回去的路上还读完了原著~

带着地球去流浪,硬核的外表之下残酷却又浪漫。

《飞驰人生》

7.5分

开心地笑一笑就好啦~

《天注定》

真实,是真的真实

《血钻》

沉重的话题..

《太空救援》

毛子的诚意之作,根据历史真实事件改编。很棒

《星际穿越》

好看好看好看

《大佛普拉斯》

人生真的好孤独呀,我们作为朋友,你却一点都不了解我;我们作为爱人,你却想要杀掉我;我们作为亲人,你却让我闭嘴。
就让我做一个追逐海浪的人好了,没有故乡,在世界上仅剩的一张摇篮上,抱着你的遗像,用沉默祝福你,用愤怒度化你,用夏天的雨纪念你。

底层的黑白与上层的彩色,让我们说什么好呢。

片中金句:

我想现在虽然是太空时代
人类早就可以坐太空船去月球
但永远无法探索别人内心的宇宙

《地心引力》

没《太空救援》好看

《隐秘而伟大》

还是多好玩的..

《垫底辣妹》

挺励志的

《妇联4》

我竟然看了两遍。。

《极品职业》

喜剧与犯罪,国内有龙虾刑警

《铁拳男人》

告诉了我一个真正的男人应该是什么样的

《雷神3》

补课

《钢铁侠3》

补课

《Free.Solo》

震撼。

做自己感兴趣的事情并以此养活自己,再和喜欢的人在一起,这才是真正的幸福呀。

《使徒行者》

贪玩蓝月巨头齐聚?

好兄弟。

《隐藏人物》

告诉我们男女是平等的,不同肤色的人也是平等的。

我觉得不同地域的人也是平等的,真正不平等是知识,是修养,是内心…

《复仇者联盟》

复习

《追龙》

五亿探长雷洛与跛豪

《瘦身男女》

以前的港片真的耐看,是风格的原因吧。

《逃学威龙》

要是不知道看啥,看星爷的片是不会错的

《钢铁侠2》

陪阿昆复习

《复仇者联盟3》

复习

《百万美元宝贝》

需要看一下

《垂直极限》

户外大片

《蚁人1》

pass

《蚁人2》

pass

《二十二》

唉

《国家破产之日》

国家破产,只有七天

《过春天》

为啥电影里的青春都这么叛逆

《狮子王》

转眼两年,u are more than you have became

《恶人传》

拳拳到肉,爽片。

不过逻辑还是有小瑕疵,瑕不掩瑜。

《哪吒》

好的 我要去二刷,下一部《姜子牙》的钱先放这儿了。

《寿司之神》

2019-07-30晚上看

《蝙蝠侠:黑暗骑士》

牛逼

《猜火车》

青春是五颜六色的。

莫名其妙的悲伤,无处安放的彷徨,自由自在的颓废。

个性,情感,想法。

《钢琴家》

自由平等民主和谐

《飞跃疯人院》

待看

《海蒂与爷爷》

这也太TM治愈了吧!!

《寄生虫》

很现实,利己主义与贪得无厌。

《海盗电台》

很👍地一部音乐片。

自由、民权、性解放、同性恋等很多点都被提到了。 不评价且尊重个体的差异,是我觉得大部分解放运动的根本要求。

《那人那山那水》

啊啊啊啊啊啊,为什么感情这么质朴,风景这么美!

《摄像机不要停》

大反转的喜剧

《重金属囧途》

重金属还是欣赏不来呀…

《波西米亚狂想曲》

没想到这么多耳熟能详的歌都是来自这个乐队。

《最后一球》

好电影

《暖》

待看

《海上钢琴师》

表达了一种人与社会的关系,以及人该怎么样去面对孤独。

《中国机长》

好看

《2001太空漫游》

《花火》

2019读书记录

Posted on 2019-07-19

遍历目录->随意翻阅->细读与勾画笔记->思维导图?->读书笔记

技术类

  • [x] 《统计学习方法》
  • [x] 《Spark快速大数据分析》
  • [ ] 《Design Data-intensive Application》
  • [x] 《费马大定理》
  • [x] 《网站分析实战》 掌握数据分析技能必看!
  • [x] 《Python核心编程》 必看
  • [x] 《PHP-MySQL基本教程》 chapter1 后续主要和建站相关,后续跟着菜鸟教程走了一遍
  • [x] 《概率论与数理统计笔记》
  • [x] 《计算广告》
  • [x] 《Hive编程指南》
  • [ ] 《Head First Java》
  • [x] 《机器学习实战》ing
  • [x] 《数据仓库》

人文类

  • [x] 《了不起的盖茨比》
  • [x] 《人间失格》
  • [x] 《活法》
  • [x] 《菜根谭》
  • [x] 《老人与海》
  • [x] 《追风筝的人》
  • [x] 《回答不了》
  • [x] 《愿生命从容》 — 周国平讲座
  • [x] 《切尔洛贝利的悲鸣》
  • [x] 《曾国潘家书》
  • [x] 《干法》 — 工作是我们最核心输入和输出的过程。建议和《活法》一起读。
  • [x] 《当我谈跑步时,我谈些什么》
  • [x] 《重说中国近代史》
  • [x] 《动物农场》
  • [x] 《北野武的小酒馆》
  • [ ] 《一个叫欧维的男人决定去死》ing
  • [ ] 《毛选 第二卷》ing
  • [x] 《人生的智慧》 — 快速翻阅

社科类

  • [ ] 《经济学原理》ing
  • [ ] 《如何阅读一本书》
  • [x] 《上帝掷骰子吗-量子物理史话》
  • [x] 《娱乐至死》
  • [ ] 《博弈论的诡计》
  • [x] 《长尾理论》
  • [x] 《随机漫步的傻瓜》
  • [x] 《被讨厌的勇气》
  • [ ] 《失控》ing

看到一半放弃了

  • 《漫长的告别》 22%,不喜欢这种类型
  • 《人类群星闪耀时》 — 看了第一章之后选择放弃,并没有兴趣..

201904放弃看《漫长的告别》,看了前22%,内容并没引起我太大的兴趣

读书 也是 很看状态的 , 不需要去强求自己 干啥

20190508 在读周国平的《愿生命从容》,写下其中一句金句:
在我看来,一个人若能做自己喜欢做的事,并且靠这养活自己,又能和自己喜欢的人在一起,并且使他(她)也感到快乐,即可称幸福

20190804 《网站分析实战》

  • 分析三板斧:对比分析,趋势分析,细分分析

20190808 《当我谈跑步时,我谈些什么》

  • 跟《禅与摩托车维修艺术》异曲同工之妙
  • 菲兹杰拉德的真粉丝
  • 这本书真的有80%在谈跑步!
  • 坚持的理由零星半点,放弃的理由一大卡车。
  • 孤独感是我们感知自己存在的必需品。

20190811 《Python核心编程》
收获很多,还要看第二遍。

20190914 《动物农场》
印象深刻,不谈政治。

20191024 《长尾理论》
核心点:长期以往,个体的选择很少,原因在于信息不对称以及工业不够发达。随着数字经济的到来,在技术的加持下,个体的需求被释放,不同行业里,蛋糕或是变大,或是重新分配,给与了人们很多的机会。

20191116 《北野武的小酒馆》

20191205 《被讨厌的勇气》

好书,书中很多观点十分受用。

人的所有烦恼都来自人际关系。

MySQL索引

Posted on 2019-07-18

MySQL的知识还是很重要的,慢慢总结,这里先讲索引。

概述

打个比方,数据库的存取过程就跟我们写日记一样。索引就像目录,文字就是数据,时不时我们会回头看看已经写下的日记。

索引是加快查询最重要的技术,如果不适用索引的话,MySQL必须从第一条记录开始遍历整张表直到找到相关行。相应地,表如果越大,花费的时间则会越多。我们这里就先说一下索引到底是什么、怎么使用索引来改善我们的查询性能以及索引可能给我们带来的影响性能的情况。

索引的本质

MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构。不过实际上,索引也是一张表,该表保存了主键与索引字段,并指向实体表的记录。

查询功能是数据库最基本也是最重要的功能之一,越快越好的查询性能也是大家的共同需求,借助于现在利器查询算法(比如二分查找,二叉树查找)等,数据库工程师们实现了这一目标。

每种查找算法都只能应用于特定的数据结构之上,例如二分查找要求被检索数据有序,而二叉树查找只能应用于二叉查找树上,但是数据本身的组织结构不可能完全满足各种数据结构(例如,理论上不可能同时将两列都按顺序进行组织),所以,在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构上实现高级查找算法。这种数据结构,就是索引。

索引的使用

索引的存储分类

MySQL目前提供了一下四种索引:

  • B-Tree索引:最常用最常见的索引,需要深入了解
  • HASH索引:只有Memory引擎支持,使用场景简单
  • R-Tree索引:空间索引是MyISAM的一种特殊索引类型,主要用于地理空间数据类型
  • Full-text索引:全文索引也是MyISAM的一种特殊索引类型

B-Tree的索引类型

  • 普通索引: 最基本的索引类型,没有唯一性的限制
  • UNIQUE索引:表示唯一的,不允许重复的索引
  • 主键(PRIMARY KEY):唯一索引的一种,必须指定为“PRIMARY KEY”,每个表只能有一个主键,是查询速度的索引。

索引的语法

设置索引

我们可以create table是指定索引,也可以后期alter table或者create index来创建索引。

alter table三种索引均可创建

1
2
3
4
5
6
7
8
9
10
-- alter table 

-- 普通索引
alter table xxx add index index_name (column_list)

-- unique索引(必须唯一,NULL除外)
alter table xxx add unique index index_name (column_list)

-- primary key(必须唯一,且不为null)
alter table xxx add primary key (column_list)

create index只可以创建普通索引和unique索引

1
2
3
4
5
6
-- create index

-- 普通索引
create index index_name on xxx (column_list)
-- unique索引
create unique index index_name on xxx(column_list)

删除索引

drop就完事儿le

1
2
drop index index_name on xxx;
alter table xxx drop index index_name;
查看索引
1
2
show index from xxx;
show keys from xxx;
使用索引

MySQL只对<,<=,=,>,>=,between,in和like xxx%这样的查询条件生效。

索引的选择原则

  1. 较为频繁做为查询条件的字段应该设置索引(where条件 和 join条件)
  2. 唯一性太差的字段不适合做索引
  3. 更新特别频繁的字段不适合做索引
  4. 不做查询条件的字段不设置索引

索引的弊端

前文说到,索引也是一张表。于是我们更新数据的时候,同时也会更新索引,由此增加了IO量和更新索引带来的计算量,并且索引也会占空间。所以主要问题有俩

  • 更新索引带来的性能与IO消耗
  • 占用了更多的存储空间

参考

  1. MySQL-索引
  2. MySQL索引-菜鸟教程
  3. MySQL联合索引最右匹配原则

哈巴攀登笔记

Posted on 2019-07-07

衣食住行的情况

出行

周五晚航班从北京出发,周六一早到达丽江,然后乘坐到香格里拉的大巴在虎跳峡镇下车(中午),乘坐哈巴村民的往返于虎跳峡镇的面包车去往哈巴村,过了中虎跳的那一段路很险,下午四点左右到达哈巴村。

住宿

第一晚住哈巴村如玉酒店,150一个标间,感觉还挺爽的。

第二天上大本营,不过我们重装上去的,是自己搭的帐篷。以后雨季在外面搭帐篷睡觉,要好好评估下是否必要,这次体验不太好,主要有两点:1. 装备重;2. 收拾不好收拾,湿且重。

食物

这次食物带少了,是个大问题。以后食物要按照超过20%的准备,而且要大概规划好每一顿吃些啥。这次水倒是准备得刚刚好,正常徒步,我的水量是1.2L到1.5L左右,可以准备两瓶矿泉水和一瓶功能饮料。

衣服

大叶迷彩的冲锋衣很好用,凯乐石的裤子也不错,优衣库的小马甲很到位,这一趟装备都很给力,一点没出岔子。

常用穿法(可以hold住大多数环境):

  • 厚羊毛袜 + 高帮运动鞋 (实战表示,一点味道都灭有)
  • 徒步长裤 + 护膝 + 秋裤(晚上钻睡袋用)
  • 速干 + 羽绒小马甲 + 羽绒衣 + 冲锋衣
  • 魔术头巾(脖子上吸汗 + 隔离速干衣) + 手表 + 帽子(华山五块钱的毛线帽。。。还真挺好用) + 户外眼镜

攀登细节

在哈巴村找到老三(三哥)作为向导,300一天。

第一天早上9点出发大本营,晃悠接近六个小时之后到达大本营。哈巴的大本营十分好,个人基本可以只带衣服和冲顶用的装备即可,在大本营吃住都不成问题,晚上七八点的时候,外面雾气朦胧,我们在里面围着火塘烧柴火烤火,也是一种很好的体验了。
烤火
第二天早上02:40起床,吃过向导准备好的早饭,给保温杯装上热水,03:30迎着小雨,出发了。依次经过密林->大石坡->碎石坡->白石坡->绝望坡(冰坡)->月亮湾之后,09:06登顶成功。在山顶呆了半个多小时之后,09:48开始下撤,14:15到达大本营,吃过午饭之后15:30继续下撤,18:07下撤到哈巴村(重装下撤是真的坑。。。)
山路夜行
坡0
坡1
冰坡
山顶的旺仔
下撤的路上
洗澡吃肉喝酒睡觉。

利用Crontab命名完成定时任务

Posted on 2019-06-27

crontab是干啥的

通过crontab命名,我们可以在固定的时间间隔执行指定的系统命名或者shell script脚本。时间间隔的单位分别是分、小时、日、月、周及以上任意组合,想定时跑啥就干啥+

crontab怎么用

1.命名格式

1
2
crontab [-u user] file
crontab [-u user] [ -e | -l | -r ]

2.命令参数

  • -u : 设定某个用户的crontab服务
  • file : 表示命令文件,crontab会执行这个命名文件,如果没有文件,则接受标准输入(键盘)上键入的命令,并将它们载入crontab
  • -e : 编辑crontab文件内容
  • -l : 显示crontab文件内容
  • -r : 从/var/spool/cron目录中删除某个用户的crontab文件,如果不指定用户,则默认删除当前用户的crontab文件。
  • -i : 在删除用户的crontab文件时给确认提示

3.文件格式

分 时 日 月 星期 要运行的命令

  • 第一列:分钟0-59
  • 第二列:小时0-23(0表示子夜)
  • 第3列:日1~31
  • 第4列:月1~12
  • 第5列:星期0~7(0和7表示星期天)
  • 第六列:要运行的命令

常用方法

编辑-e,显示-l,新建删除一般用不着,需要用的时候看~

使用实例

1.每分钟执行一个命令
1
* * * * * myCommand
2.每小时的第3和第15分钟执行
1
3,15 * * * * myCommand
3.在上午8点到11点的第3和第15分钟执行
1
3,15 8-11 * * * myCommand
4.每天18 : 00至23 : 00之间每隔30分钟执行我的脚本
1
*/30 18-23 * * * cd /home/xxx;sh xxx.sh

crontab的坑

环境变量

有时候我们使用crontab去执行一个定时任务,发现在shell里面手动执行是没有问题的,但是无法自动执行。导致这种问题的原因一般是crontab文件中没有配置环境变量造成的。

在crontab文件中定义多个调度任务时,需要特别注环境变量的设置,因为我们手动执行某个任务时,是在当前shell环境下进行的,程序当然能找到环境变量,而系统自动执行任务调度时,是不会加载任何环境变量的,因此,就需要在crontab文件中指定任务运行所需的所有环境变量,这样,系统执行任务调度时就没有问题了

不要假定cron知道所需要的特殊环境,它其实并不知道,我们使用的时候,需要注意以下三点:

  1. 脚本执行中文件路径要写全局路径
  2. 脚本执行要用到java或其他环境变量时,通过source命令引入环境变量 — 这个还没用过
  3. 当手动执行脚本OK,但是crontab死活不执行时,很可能是环境变量惹的祸
    1
    2
    3
    #!/usr/bin/env bash
    export JAVA_HOME='/usr/java/xxx'
    export HADOOP_HOME='/home/maintain/hadoop/xxxx'

第三点真的是踩的陨石巨坑!!!

清理邮件日志

每条任务调度执行完毕,系统都会将任务输出信息通过电子邮件的形式发送给当前系统用户,这样日积月累,日志信息会非常大,可能会影响系统的正常运行,因此对每条任务进行重定向处理很重要,比如可以这么设置,忽略日志输出:

1
* * * * * date > /logs/time.log 2>&1

“/logs/time.log 2>&1”表示先将标准输出重定向到/dev/null,然后将标准错误重定向到标准输出

其他问题

  • 在crontab中%是有特殊含义的,表示换行的意思。如果要用的话必须进行转义%,如经常用的date ‘+%Y%m%d’在crontab里是不会执行的,应该换成date ‘+%Y%m%d’
  • 当crontab失效时,可以尝试/etc/init.d/crond restart解决问题。或者查看日志看某个job有没有执行/报错tail -f /var/log/cron。
  • 不要乱删。。。
1…456…12
zhangyang

zhangyang

120 posts
39 tags
© 2022 zhangyang
Powered by Hexo
|
Theme — NexT.Mist v5.1.4