this is a cheatsheet, is used for get help quickly.

# Bash

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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
##############################################################################
# 常用快捷键(默认使用 Emacs 键位)
##############################################################################

CTRL+A # 移动到行首,同 <Home>
CTRL+B # 向后移动,同 <Left>
CTRL+C # 结束当前命令
CTRL+D # 删除光标前的字符,同 <Delete> ,或者没有内容时,退出会话
CTRL+E # 移动到行末,同 <End>
CTRL+F # 向前移动,同 <Right>
CTRL+G # 退出当前编辑(比如正在 CTRL+R 搜索历史时)
CTRL+H # 删除光标左边的字符,同 <Backspace>
CTRL+K # 删除光标位置到行末的内容
CTRL+L # 清屏并重新显示
CTRL+N # 移动到命令历史的下一行,同 <Down>
CTRL+O # 类似回车,但是会显示下一行历史
CTRL+P # 移动到命令历史的上一行,同 <Up>
CTRL+R # 历史命令反向搜索,使用 CTRL+G 退出搜索
CTRL+S # 历史命令正向搜索,使用 CTRL+G 退出搜索
CTRL+T # 交换前后两个字符
CTRL+U # 删除字符到行首
CTRL+V # 输入字符字面量,先按 CTRL+V 再按任意键
CTRL+W # 删除光标左边的一个单词
CTRL+X # 列出可能的补全
CTRL+Y # 粘贴前面 CTRL+u/k/w 删除过的内容
CTRL+Z # 暂停前台进程返回 bash,需要时可用 fg 将其切换回前台
CTRL+_ # 撤销(undo),有的终端将 CTRL+_ 映射为 CTRL+/ 或 CTRL+7

ALT+b # 向后(左边)移动一个单词
ALT+d # 删除光标后(右边)一个单词
ALT+f # 向前(右边)移动一个单词
ALT+t # 交换字符
ALT+BACKSPACE # 删除光标前面一个单词,类似 CTRL+W,但不影响剪贴板

CTRL+X CTRL+X # 连续按两次 CTRL+X,光标在当前位置和行首来回跳转
CTRL+X CTRL+E # 用你指定的编辑器,编辑当前命令


##############################################################################
# BASH 基本操作
##############################################################################

exit # 退出当前登陆
env # 显示环境变量
echo $SHELL # 显示你在使用什么 SHELL

bash # 使用 bash,用 exit 返回
which bash # 搜索 $PATH,查找哪个程序对应命令 bash
whereis bash # 搜索可执行,头文件和帮助信息的位置,使用系统内建数据库
whatis bash # 查看某个命令的解释,一句话告诉你这是干什么的

clear # 清初屏幕内容
reset # 重置终端(当你不小心 cat 了一个二进制,终端状态乱掉时使用)


##############################################################################
# 目录操作
##############################################################################

cd # 返回自己 $HOME 目录
cd {dirname} # 进入目录
pwd # 显示当前所在目录
mkdir {dirname} # 创建目录
mkdir -p {dirname} # 递归创建目录
pushd {dirname} # 目录压栈并进入新目录
popd # 弹出并进入栈顶的目录
dirs -v # 列出当前目录栈
cd - # 回到之前的目录
cd -{N} # 切换到目录栈中的第 N个目录,比如 cd -2 将切换到第二个


##############################################################################
# 文件操作
##############################################################################

ls # 显示当前目录内容,后面可接目录名:ls {dir} 显示指定目录
ls -l # 列表方式显示目录内容,包括文件日期,大小,权限等信息
ls -1 # 列表方式显示目录内容,只显示文件名称,减号后面是数字 1
ls -a # 显示所有文件和目录,包括隐藏文件(.开头的文件/目录名)
ln -s {fn} {link} # 给指定文件创建一个软链接
cp {src} {dest} # 拷贝文件,cp -r dir1 dir2 可以递归拷贝(目录)
rm {fn} # 删除文件,rm -r 递归删除目录,rm -f 强制删除
mv {src} {dest} # 移动文件,如果 dest 是目录,则移动,是文件名则覆盖
touch {fn} # 创建或者更新一下制定文件
cat {fn} # 输出文件原始内容
any_cmd > {fn} # 执行任意命令并将标准输出重定向到指定文件
more {fn} # 逐屏显示某文件内容,空格翻页,q 退出
less {fn} # 更高级点的 more,更多操作,q 退出
head {fn} # 显示文件头部数行,可用 head -3 abc.txt 显示头三行
tail {fn} # 显示文件尾部数行,可用 tail -3 abc.txt 显示尾部三行
tail -f {fn} # 持续显示文件尾部数据,可用于监控日志
nano {fn} # 使用 nano 编辑器编辑文件
vim {fn} # 使用 vim 编辑文件
diff {f1} {f2} # 比较两个文件的内容
wc {fn} # 统计文件有多少行,多少个单词
chmod 644 {fn} # 修改文件权限为 644,可以接 -R 对目录循环改权限
chgrp group {fn} # 修改文件所属的用户组
chown user1 {fn} # 修改文件所有人为 user1, chown user1:group1 fn 可以修改组
file {fn} # 检测文件的类型和编码
basename {fn} # 查看文件的名字(不包括路径)
dirname {fn} # 查看文件的路径(不包括名字)
grep {pat} {fn} # 在文件中查找出现过 pat 的内容
grep -r {pat} . # 在当前目录下递归查找所有出现过 pat 的文件内容
stat {fn} # 显示文件的详细信息


##############################################################################
# 用户管理
##############################################################################

whoami # 显示我的用户名
who # 显示已登陆用户信息,w / who / users 内容略有不同
w # 显示已登陆用户信息,w / who / users 内容略有不同
users # 显示已登陆用户信息,w / who / users 内容略有不同
passwd # 修改密码,passwd {user} 可以用于 root 修改别人密码
finger {user} # 显示某用户信息,包括 id, 名字, 登陆状态等
adduser {user} # 添加用户
deluser {user} # 删除用户
w # 查看谁在线
su # 切换到 root 用户
su - # 切换到 root 用户并登陆(执行登陆脚本)
su {user} # 切换到某用户
su -{user} # 切换到某用户并登陆(执行登陆脚本)
id {user} # 查看用户的 uid,gid 以及所属其他用户组
id -u {user} # 打印用户 uid
id -g {user} # 打印用户 gid
write {user} # 向某用户发送一句消息
last # 显示最近用户登陆列表
last {user} # 显示登陆记录
lastb # 显示失败登陆记录
lastlog # 显示所有用户的最近登陆记录
sudo {command} # 以 root 权限执行某命令


##############################################################################
# 进程管理
##############################################################################

ps # 查看当前会话进程
ps ax # 查看所有进程,类似 ps -e
ps aux # 查看所有进程详细信息,类似 ps -ef
ps auxww # 查看所有进程,并且显示进程的完整启动命令
ps -u {user} # 查看某用户进程
ps axjf # 列出进程树
ps xjf -u {user} # 列出某用户的进程树
ps -eo pid,user,command # 按用户指定的格式查看进程
ps aux | grep httpd # 查看名为 httpd 的所有进程
ps --ppid {pid} # 查看父进程为 pid 的所有进程
pstree # 树形列出所有进程,pstree 默认一般不带,需安装
pstree {user} # 进程树列出某用户的进程
pstree -u # 树形列出所有进程以及所属用户
pgrep {procname} # 搜索名字匹配的进程的 pid,比如 pgrep apache2

kill {pid} # 结束进程
kill -9 {pid} # 强制结束进程,9/SIGKILL 是强制不可捕获结束信号
kill -KILL {pid} # 强制执行进程,kill -9 的另外一种写法
kill -l # 查看所有信号
kill -l TERM # 查看 TERM 信号的编号
killall {procname} # 按名称结束所有进程
pkill {procname} # 按名称结束进程,除名称外还可以有其他参数

top # 查看最活跃的进程
top -u {user} # 查看某用户最活跃的进程

any_command & # 在后台运行某命令,也可用 CTRL+Z 将当前进程挂到后台
jobs # 查看所有后台进程(jobs)
bg # 查看后台进程,并切换过去
fg # 切换后台进程到前台
fg {job} # 切换特定后台进程到前台

trap cmd sig1 sig2 # 在脚本中设置信号处理命令
trap "" sig1 sig2 # 在脚本中屏蔽某信号
trap - sig1 sig2 # 恢复默认信号处理行为

nohup {command} # 长期运行某程序,在你退出登陆都保持它运行
nohup {command} & # 在后台长期运行某程序
disown {PID|JID} # 将进程从后台任务列表(jobs)移除

wait # 等待所有后台进程任务结束


##############################################################################
# 常用命令:SSH / 系统信息 / 网络
##############################################################################

ssh user@host # 以用户 user 登陆到远程主机 host
ssh -p {port} user@host # 指定端口登陆主机
ssh-copy-id user@host # 拷贝你的 ssh key 到远程主机,避免重复输入密码
scp {fn} user@host:path # 拷贝文件到远程主机
scp user@host:path dest # 从远程主机拷贝文件回来
scp -P {port} ... # 指定端口远程拷贝文件

uname -a # 查看内核版本等信息
man {help} # 查看帮助
man -k {keyword} # 查看哪些帮助文档里包含了该关键字
info {help} # 查看 info pages,比 man 更强的帮助系统
uptime # 查看系统启动时间
date # 显示日期
cal # 显示日历
vmstat # 显示内存和 CPU 使用情况
vmstat 10 # 每 10 秒打印一行内存和 CPU情况,CTRL+C 退出
free # 显示内存和交换区使用情况
df # 显示磁盘使用情况
du # 显示当前目录占用,du . --max-depth=2 可以指定深度
uname # 显示系统版本号
hostname # 显示主机名称
showkey -a # 查看终端发送的按键编码

ping {host} # ping 远程主机并显示结果,CTRL+C 退出
ping -c N {host} # ping 远程主机 N 次
traceroute {host} # 侦测路由连通情况
mtr {host} # 高级版本 traceroute
host {domain} # DNS 查询,{domain} 前面可加 -a 查看详细信息
whois {domain} # 取得域名 whois 信息
dig {domain} # 取得域名 dns 信息
route -n # 查看路由表
netstat -a # 列出所有端口
netstat -an # 查看所有连接信息,不解析域名
netstat -anp # 查看所有连接信息,包含进程信息(需要 sudo)
netstat -l # 查看所有监听的端口
netstat -t # 查看所有 TCP 链接
netstat -lntu # 显示所有正在监听的 TCP 和 UDP 信息
netstat -lntup # 显示所有正在监听的 socket 及进程信息
netstat -i # 显示网卡信息
netstat -rn # 显示当前系统路由表,同 route -n
ss -an # 比 netstat -an 更快速更详细
ss -s # 统计 TCP 的 established, wait 等

wget {url} # 下载文件,可加 --no-check-certificate 忽略 ssl 验证
wget -qO- {url} # 下载文件并输出到标准输出(不保存)
curl -sL {url} # 同 wget -qO- {url} 没有 wget 的时候使用

sz {file} # 发送文件到终端,zmodem 协议
rz # 接收终端发送过来的文件


##############################################################################
# 变量操作
##############################################################################

varname=value # 定义变量
varname=value command # 定义子进程变量并执行子进程
echo $varname # 查看变量内容
echo $$ # 查看当前 shell 的进程号
echo $! # 查看最近调用的后台任务进程号
echo $? # 查看最近一条命令的返回码
export VARNAME=value # 设置环境变量(将会影响到子进程)

array[0]=valA # 定义数组
array[1]=valB
array[2]=valC
array=([0]=valA [1]=valB [2]=valC) # 另一种方式
array=(valA valB valC) # 另一种方式

${array[i]} # 取得数组中的元素
${#array[@]} # 取得数组的长度
${#array[i]} # 取得数组中某个变量的长度

declare -a # 查看所有数组
declare -f # 查看所有函数
declare -F # 查看所有函数,仅显示函数名
declare -i # 查看所有整数
declare -r # 查看所有只读变量
declare -x # 查看所有被导出成环境变量的东西
declare -p varname # 输出变量是怎么定义的(类型+值)

${varname:-word} # 如果变量不为空则返回变量,否则返回 word
${varname:=word} # 如果变量不为空则返回变量,否则赋值成 word 并返回
${varname:?message} # 如果变量不为空则返回变量,否则打印错误信息并退出
${varname:+word} # 如果变量不为空则返回 word,否则返回 null
${varname:offset:len} # 取得字符串的子字符串

${variable#pattern} # 如果变量头部匹配 pattern,则删除最小匹配部分返回剩下的
${variable##pattern} # 如果变量头部匹配 pattern,则删除最大匹配部分返回剩下的
${variable%pattern} # 如果变量尾部匹配 pattern,则删除最小匹配部分返回剩下的
${variable%%pattern} # 如果变量尾部匹配 pattern,则删除最大匹配部分返回剩下的
${variable/pattern/str} # 将变量中第一个匹配 pattern 的替换成 str,并返回
${variable//pattern/str} # 将变量中所有匹配 pattern 的地方替换成 str 并返回

${#varname} # 返回字符串长度

*(patternlist) # 零次或者多次匹配
+(patternlist) # 一次或者多次匹配
?(patternlist) # 零次或者一次匹配
@(patternlist) # 单词匹配
!(patternlist) # 不匹配

array=($text) # 按空格分隔 text 成数组,并赋值给变量
IFS="/" array=($text) # 按斜杆分隔字符串 text 成数组,并赋值给变量
text="${array[*]}" # 用空格链接数组并赋值给变量
text=$(IFS=/; echo "${array[*]}") # 用斜杠链接数组并赋值给变量

A=( foo bar "a b c" 42 ) # 数组定义
B=("${A[@]:1:2}") # 数组切片:B=( bar "a b c" )
C=("${A[@]:1}") # 数组切片:C=( bar "a b c" 42 )
echo "${B[@]}" # bar a b c
echo "${B[1]}" # a b c
echo "${C[@]}" # bar a b c 42
echo "${C[@]: -2:2}" # a b c 42 减号前的空格是必须的

$(UNIX command) # 运行命令,并将标准输出内容捕获并返回
varname=$(id -u user) # 将用户名为 user 的 uid 赋值给 varname 变量

num=$(expr 1 + 2) # 兼容 posix sh 的计算,使用 expr 命令计算结果
num=$(expr $num + 1) # 数字自增
expr 2 \* \( 2 + 3 \) # 兼容 posix sh 的复杂计算,输出 10

num=$((1 + 2)) # 计算 1+2 赋值给 num,使用 bash 独有的 $((..)) 计算
num=$(($num + 1)) # 变量递增
num=$((num + 1)) # 变量递增,双括号内的 $ 可以省略
num=$((1 + (2 + 3) * 2)) # 复杂计算


##############################################################################
# 事件指示符
##############################################################################

!! # 上一条命令
!^ # 上一条命令的第一个单词
!:n # 上一条命令的第n个单词
!:n-$ # 上一条命令的第n个单词到最后一个单词
!$ # 上一条命令的最后一个单词
!-n:$ # 上n条命令的最后一个单词
!string # 最近一条包含string的命令
!^string1^string2 # 最近一条包含string1的命令, 快速替换string1为string2
!# # 本条命令之前所有的输入内容
!#:n # 本条命令之前的第n个单词, 快速备份cp /etc/passwd !#:1.bak


##############################################################################
# 函数
##############################################################################

# 定义一个新函数
function myfunc() {
# $1 代表第一个参数,$N 代表第 N 个参数
# $# 代表参数个数
# $0 代表被调用者自身的名字
# $@ 代表所有参数,类型是个数组,想传递所有参数给其他命令用 cmd "$@"
# $* 空格链接起来的所有参数,类型是字符串
{shell commands ...}
}

myfunc # 调用函数 myfunc
myfunc arg1 arg2 arg3 # 带参数的函数调用
myfunc "$@" # 将所有参数传递给函数
myfunc "${array[@]}" # 将一个数组当作多个参数传递给函数
shift # 参数左移

unset -f myfunc # 删除函数
declare -f # 列出函数定义


##############################################################################
# 条件判断(兼容 posix sh 的条件判断):man test
##############################################################################

statement1 && statement2 # and 操作符
statement1 || statement2 # or 操作符

exp1 -a exp2 # exp1 和 exp2 同时为真时返回真(POSIX XSI扩展)
exp1 -o exp2 # exp1 和 exp2 有一个为真就返回真(POSIX XSI扩展)
( expression ) # 如果 expression 为真时返回真,输入注意括号前反斜杆
! expression # 如果 expression 为假那返回真

str1 = str2 # 判断字符串相等,如 [ "$x" = "$y" ] && echo yes
str1 != str2 # 判断字符串不等,如 [ "$x" != "$y" ] && echo yes
str1 < str2 # 字符串小于,如 [ "$x" \< "$y" ] && echo yes
str2 > str2 # 字符串大于,注意 < 或 > 是字面量,输入时要加反斜杆
-n str1 # 判断字符串不为空(长度大于零)
-z str1 # 判断字符串为空(长度等于零)

-a file # 判断文件存在,如 [ -a /tmp/abc ] && echo "exists"
-d file # 判断文件存在,且该文件是一个目录
-e file # 判断文件存在,和 -a 等价
-f file # 判断文件存在,且该文件是一个普通文件(非目录等)
-r file # 判断文件存在,且可读
-s file # 判断文件存在,且尺寸大于0
-w file # 判断文件存在,且可写
-x file # 判断文件存在,且执行
-N file # 文件上次修改过后还没有读取过
-O file # 文件存在且属于当前用户
-G file # 文件存在且匹配你的用户组
file1 -nt file2 # 文件1 比 文件2 新
file1 -ot file2 # 文件1 比 文件2 旧

num1 -eq num2 # 数字判断:num1 == num2
num1 -ne num2 # 数字判断:num1 != num2
num1 -lt num2 # 数字判断:num1 < num2
num1 -le num2 # 数字判断:num1 <= num2
num1 -gt num2 # 数字判断:num1 > num2
num1 -ge num2 # 数字判断:num1 >= num2


##############################################################################
# 分支控制:if 和经典 test,兼容 posix sh 的条件判断语句
##############################################################################

test {expression} # 判断条件为真的话 test 程序返回0 否则非零
[ expression ] # 判断条件为真的话返回0 否则非零

test "abc" = "def" # 查看返回值 echo $? 显示 1,因为条件为假
test "abc" != "def" # 查看返回值 echo $? 显示 0,因为条件为真

test -a /tmp; echo $? # 调用 test 判断 /tmp 是否存在,并打印 test 的返回值
[ -a /tmp ]; echo $? # 和上面完全等价,/tmp 肯定是存在的,所以输出是 0

test cond && cmd1 # 判断条件为真时执行 cmd1
[ cond ] && cmd1 # 和上面完全等价
[ cond ] && cmd1 || cmd2 # 条件为真执行 cmd1 否则执行 cmd2

# 判断 /etc/passwd 文件是否存在
# 经典的 if 语句就是判断后面的命令返回值为0的话,认为条件为真,否则为假
if test -e /etc/passwd; then
echo "alright it exists ... "
else
echo "it doesn't exist ... "
fi

# 和上面完全等价,[ 是个和 test 一样的可执行程序,但最后一个参数必须为 ]
# 这个名字为 "[" 的可执行程序一般就在 /bin 或 /usr/bin 下面,比 test 优雅些
if [ -e /etc/passwd ]; then
echo "alright it exists ... "
else
echo "it doesn't exist ... "
fi

# 和上面两个完全等价,其实到 bash 时代 [ 已经是内部命令了,用 enable 可以看到
[ -e /etc/passwd ] && echo "alright it exists" || echo "it doesn't exist"

# 判断变量的值
if [ "$varname" = "foo" ]; then
echo "this is foo"
elif [ "$varname" = "bar" ]; then
echo "this is bar"
else
echo "neither"
fi

# 复杂条件判断,注意 || 和 && 是完全兼容 POSIX 的推荐写法
if [ $x -gt 10 ] && [ $x -lt 20 ]; then
echo "yes, between 10 and 20"
fi

# 可以用 && 命令连接符来做和上面完全等价的事情
[ $x -gt 10 ] && [ $x -lt 20 ] && echo "yes, between 10 and 20"

# 小括号和 -a -o 是 POSIX XSI 扩展写法,小括号是字面量,输入时前面要加反斜杆
if [ \( $x -gt 10 \) -a \( $x -lt 20 \) ]; then
echo "yes, between 10 and 20"
fi

# 同样可以用 && 命令连接符来做和上面完全等价的事情
[ \( $x -gt 10 \) -a \( $x -lt 20 \) ] && echo "yes, between 10 and 20"


# 判断程序存在的话就执行
[ -x /bin/ls ] && /bin/ls -l

# 如果不考虑兼容 posix sh 和 dash 这些的话,可用 bash 独有的 ((..)) 和 [[..]]:
https://www.ibm.com/developerworks/library/l-bash-test/index.html


##############################################################################
# 流程控制:while / for / case / until
##############################################################################

# while 循环
while condition; do
statements
done

i=1
while [ $i -le 10 ]; do
echo $i;
i=$(expr $i + 1)
done

# for 循环:上面的 while 语句等价
for i in {1..10}; do
echo $i
done

for name [in list]; do
statements
done

# for 列举某目录下面的所有文件
for f in /home/*; do
echo $f
done

# bash 独有的 (( .. )) 语句,更接近 C 语言,但是不兼容 posix sh
for (( initialisation ; ending condition ; update )); do
statements
done

# 和上面的写法等价
for ((i = 0; i < 10; i++)); do echo $i; done

# case 判断
case expression in
pattern1 )
statements ;;
pattern2 )
statements ;;
* )
otherwise ;;
esac

# until 语句
until condition; do
statements
done

# select 语句
select name [in list]; do
statements that can use $name
done


##############################################################################
# 命令处理
##############################################################################

command ls # 忽略 alias 直接执行程序或者内建命令 ls
builtin cd # 忽略 alias 直接运行内建的 cd 命令
enable # 列出所有 bash 内置命令,或禁止某命令
help {builtin_command} # 查看内置命令的帮助(仅限 bash 内置命令)

eval $script # 对 script 变量中的字符串求值(执行)


##############################################################################
# 输出/输入 重定向
##############################################################################

cmd1 | cmd2 # 管道,cmd1 的标准输出接到 cmd2 的标准输入
< file # 将文件内容重定向为命令的标准输入
> file # 将命令的标准输出重定向到文件,会覆盖文件
>> file # 将命令的标准输出重定向到文件,追加不覆盖
>| file # 强制输出到文件,即便设置过:set -o noclobber
n>| file # 强制将文件描述符 n的输出重定向到文件
<> file # 同时使用该文件作为标准输入和标准输出
n<> file # 同时使用文件作为文件描述符 n 的输出和输入
n> file # 重定向文件描述符 n 的输出到文件
n< file # 重定向文件描述符 n 的输入为文件内容
n>& # 将标准输出 dup/合并 到文件描述符 n
n<& # 将标准输入 dump/合并 定向为描述符 n
n>&m # 文件描述符 n 被作为描述符 m 的副本,输出用
n<&m # 文件描述符 n 被作为描述符 m 的副本,输入用
&>file # 将标准输出和标准错误重定向到文件
<&- # 关闭标准输入
>&- # 关闭标准输出
n>&- # 关闭作为输出的文件描述符 n
n<&- # 关闭作为输入的文件描述符 n
diff <(cmd1) <(cmd2) # 比较两个命令的输出


##############################################################################
# 文本处理 - cut
##############################################################################

cut -c 1-16 # 截取每行头16个字符
cut -c 1-16 file # 截取指定文件中每行头 16个字符
cut -c3- # 截取每行从第三个字符开始到行末的内容
cut -d':' -f5 # 截取用冒号分隔的第五列内容
cut -d';' -f2,10 # 截取用分号分隔的第二和第十列内容
cut -d' ' -f3-7 # 截取空格分隔的三到七列
echo "hello" | cut -c1-3 # 显示 hel
echo "hello sir" | cut -d' ' -f2 # 显示 sir
ps | tr -s " " | cut -d " " -f 2,3,4 # cut 搭配 tr 压缩字符


##############################################################################
# 文本处理 - awk / sed
##############################################################################

awk '{print $5}' file # 打印文件中以空格分隔的第五列
awk -F ',' '{print $5}' file # 打印文件中以逗号分隔的第五列
awk '/str/ {print $2}' file # 打印文件中包含 str 的所有行的第二列
awk -F ',' '{print $NF}' file # 打印逗号分隔的文件中的每行最后一列
awk '{s+=$1} END {print s}' file # 计算所有第一列的合
awk 'NR%3==1' file # 从第一行开始,每隔三行打印一行

sed 's/find/replace/' file # 替换文件中首次出现的字符串并输出结果
sed '10s/find/replace/' file # 替换文件第 10 行内容
sed '10,20s/find/replace/' file # 替换文件中 10-20 行内容
sed -r 's/regex/replace/g' file # 替换文件中所有出现的字符串
sed -i 's/find/replace/g' file # 替换文件中所有出现的字符并且覆盖文件
sed -i '/find/i\newline' file # 在文件的匹配文本前插入行
sed -i '/find/a\newline' file # 在文件的匹配文本后插入行
sed '/line/s/find/replace/' file # 先搜索行特征再执行替换
sed -e 's/f/r/' -e 's/f/r' file # 执行多次替换
sed 's#find#replace#' file # 使用 # 替换 / 来避免 pattern 中有斜杆
sed -i -r 's/^\s+//g' file # 删除文件每行头部空格
sed '/^$/d' file # 删除文件空行并打印
sed -i 's/\s\+$//' file # 删除文件每行末尾多余空格
sed -n '2p' file # 打印文件第二行
sed -n '2,5p' file # 打印文件第二到第五行


##############################################################################
# 排序 - sort
##############################################################################

sort file # 排序文件
sort -r file # 反向排序(降序)
sort -n file # 使用数字而不是字符串进行比较
sort -t: -k 3n /etc/passwd # 按 passwd 文件的第三列进行排序
sort -u file # 去重排序


##############################################################################
# 快速跳转 - https://github.com/rupa/z
##############################################################################

source /path/to/z.sh # .bashrc 中初始化 z.sh
z # 列出所有历史路径以及他们的权重
z foo # 跳到历史路径中匹配 foo 的权重最大的目录
z foo bar # 跳到历史路径中匹配 foo 和 bar 权重最大的目录
z -l foo # 列出所有历史路径中匹配 foo 的目录及权重
z -r foo # 按照最高访问次数优先进行匹配跳转
z -t foo # 按照最近访问优先进行匹配跳转


##############################################################################
# 键盘绑定
##############################################################################

bind '"\eh":"\C-b"' # 绑定 ALT+h 为光标左移,同 CTRL+b / <Left>
bind '"\el":"\C-f"' # 绑定 ALT+l 为光标右移,同 CTRL+f / <Right>
bind '"\ej":"\C-n"' # 绑定 ALT+j 为下条历史,同 CTRL+n / <Down>
bind '"\ek":"\C-p"' # 绑定 ALT+k 为上条历史,同 CTRL+p / <Up>
bind '"\eH":"\eb"' # 绑定 ALT+H 为光标左移一个单词,同 ALT-b
bind '"\eL":"\ef"' # 绑定 ALT+L 为光标右移一个单词,同 ALT-f
bind '"\eJ":"\C-a"' # 绑定 ALT+J 为移动到行首,同 CTRL+a / <Home>
bind '"\eK":"\C-e"' # 绑定 ALT+K 为移动到行末,同 CTRL+e / <End>
bind '"\e;":"ls -l\n"' # 绑定 ALT+; 为执行 ls -l 命令


##############################################################################
# 网络管理:ip / ifconfig / nmap ...
##############################################################################

ip a # 显示所有网络地址,同 ip address
ip a show eth1 # 显示网卡 IP 地址
ip a add 172.16.1.23/24 dev eth1 # 添加网卡 IP 地址
ip a del 172.16.1.23/24 dev eth1 # 删除网卡 IP 地址
ip link show dev eth0 # 显示网卡设备属性
ip link set eth1 up # 激活网卡
ip link set eth1 down # 关闭网卡
ip link set eth1 address {mac} # 修改 MAC 地址
ip neighbour # 查看 ARP 缓存
ip route # 查看路由表
ip route add 10.1.0.0/24 via 10.0.0.253 dev eth0 # 添加静态路由
ip route del 10.1.0.0/24 # 删除静态路由

ifconfig # 显示所有网卡和接口信息
ifconfig -a # 显示所有网卡(包括开机没启动的)信息
ifconfig eth0 # 指定设备显示信息
ifconfig eth0 up # 激活网卡
ifconfig eth0 down # 关闭网卡
ifconfig eth0 192.168.120.56 # 给网卡配置 IP 地址
ifconfig eth0 10.0.0.8 netmask 255.255.255.0 up # 配置 IP 并启动
ifconfig eth0 hw ether 00:aa:bb:cc:dd:ee # 修改 MAC 地址

nmap 10.0.0.12 # 扫描主机 1-1000 端口
nmap -p 1024-65535 10.0.0.12 # 扫描给定端口
nmap 10.0.0.0/24 # 给定网段扫描局域网内所有主机
nmap -O -sV 10.0.0.12 # 探测主机服务和操作系统版本


##############################################################################
# 有趣的命令
##############################################################################

man hier # 查看文件系统的结构和含义
man test # 查看 posix sh 的条件判断帮助
man ascii # 显示 ascii 表
getconf LONG_BIT # 查看系统是 32 位还是 64 位
bind -P # 列出所有 bash 的快捷键
mount | column -t # 漂亮的列出当前加载的文件系统
curl ip.cn # 取得外网 ip 地址和服务商信息
disown -a && exit # 关闭所有后台任务并退出
cat /etc/issue # 查看 Linux 发行版信息
lsof -i port:80 # 哪个程序在使用 80 端口?
showkey -a # 取得按键的 ASCII 码
svn diff | view - # 使用 Vim 来显示带色彩的 diff 输出
mv filename.{old,new} # 快速文件改名
time read # 使用 CTRL-D 停止,最简单的计时功能
cp file.txt{,.bak} # 快速备份文件
sudo touch /forcefsck # 强制在下次重启时扫描磁盘
find ~ -mmin 60 -type f # 查找 $HOME 目录中,60 分钟内修改过的文件
curl wttr.in/~beijing # 查看北京的天气预报
echo ${SSH_CLIENT%% *} # 取得你是从什么 IP 链接到当前主机上的
echo $[RANDOM%X+1] # 取得 1 到 X 之间的随机数
bind -x '"\C-l":ls -l' # 设置 CTRL+l 为执行 ls -l 命令
find / -type f -size +5M # 查找大于 5M 的文件
chmod --reference f1 f2 # 将 f2 的权限设置成 f1 一模一样的
curl -L cheat.sh # 速查表大全


##############################################################################
# 常用技巧
##############################################################################

# 列出最常使用的命令
history | awk '{a[$2]++}END{for(i in a){print a[i] " " i}}' | sort -rn | head

# 列出所有网络状态:ESTABLISHED / TIME_WAIT / FIN_WAIT1 / FIN_WAIT2
netstat -n | awk '/^tcp/ {++tt[$NF]} END {for (a in tt) print a, tt[a]}'

# 通过 SSH 来 mount 文件系统
sshfs name@server:/path/to/folder /path/to/mount/point

# 显示前十个运行的进程并按内存使用量排序
ps aux | sort -nk +4 | tail

# 在右上角显示时钟
while sleep 1;do tput sc;tput cup 0 $(($(tput cols)-29));date;tput rc;done&

# 从网络上的压缩文件中解出一个文件来,并避免保存中间文件
wget -qO - "http://www.tarball.com/tarball.gz" | tar zxvf -

# 性能测试:测试处理器性能
python -c "import test.pystone;print(test.pystone.pystones())"

# 性能测试:测试内存带宽
dd if=/dev/zero of=/dev/null bs=1M count=32768

# Linux 下挂载一个 iso 文件
mount /path/to/file.iso /mnt/cdrom -oloop

# 通过主机 A 直接 ssh 到主机 B
ssh -t hostA ssh hostB

# 下载一个网站的所有图片
wget -r -l1 --no-parent -nH -nd -P/tmp -A".gif,.jpg" http://example.com/images

# 快速创建项目目录
mkdir -p work/{project1,project2}/{src,bin,bak}

# 按日期范围查找文件
find . -type f -newermt "2010-01-01" ! -newermt "2010-06-01"

# 显示当前正在使用网络的进程
lsof -P -i -n | cut -f 1 -d " "| uniq | tail -n +2

# Vim 中保存一个没有权限的文件
:w !sudo tee > /dev/null %

# 在 .bashrc / .bash_profile 中加载另外一个文件(比如你保存在 github 上的配置)
source ~/github/profiles/my_bash_init.sh

# 反向代理:将外网主机(202.115.8.1)端口(8443)转发到内网主机 192.168.1.2:443
ssh -CqTnN -R 0.0.0.0:8443:192.168.1.2:443 user@202.115.8.1

# 正向代理:将本地主机的 8443 端口,通过 192.168.1.3 转发到 192.168.1.2:443
ssh -CqTnN -L 0.0.0.0:8443:192.168.1.2:443 user@192.168.1.3

# socks5 代理:把本地 1080 端口的 socks5 的代理请求通过远程主机转发出去
ssh -CqTnN -D localhost:1080 user@202.115.8.1

# 终端下正确设置 ALT 键和 BackSpace 键
http://www.skywind.me/blog/archives/2021


##############################################################################
# 有用的函数
##############################################################################

# 自动解压:判断文件后缀名并调用相应解压命令
function q-extract() {
if [ -f $1 ] ; then
case $1 in
*.tar.bz2) tar -xvjf $1 ;;
*.tar.gz) tar -xvzf $1 ;;
*.tar.xz) tar -xvJf $1 ;;
*.bz2) bunzip2 $1 ;;
*.rar) rar x $1 ;;
*.gz) gunzip $1 ;;
*.tar) tar -xvf $1 ;;
*.tbz2) tar -xvjf $1 ;;
*.tgz) tar -xvzf $1 ;;
*.zip) unzip $1 ;;
*.Z) uncompress $1 ;;
*.7z) 7z x $1 ;;
*) echo "don't know how to extract '$1'..." ;;
esac
else
echo "'$1' is not a valid file!"
fi
}

# 自动压缩:判断后缀名并调用相应压缩程序
function q-compress() {
if [ -n "$1" ] ; then
FILE=$1
case $FILE in
*.tar) shift && tar -cf $FILE $* ;;
*.tar.bz2) shift && tar -cjf $FILE $* ;;
*.tar.xz) shift && tar -cJf $FILE $* ;;
*.tar.gz) shift && tar -czf $FILE $* ;;
*.tgz) shift && tar -czf $FILE $* ;;
*.zip) shift && zip $FILE $* ;;
*.rar) shift && rar $FILE $* ;;
esac
else
echo "usage: q-compress <foo.tar.gz> ./foo ./bar"
fi
}

# 漂亮的带语法高亮的 color cat ,需要先 pip install pygments
function ccat() {
local style="monokai"
if [ $# -eq 0 ]; then
pygmentize -P style=$style -P tabsize=4 -f terminal256 -g
else
for NAME in $@; do
pygmentize -P style=$style -P tabsize=4 -f terminal256 -g "$NAME"
done
fi
}


##############################################################################
# 好玩的配置
##############################################################################

# 放到你的 ~/.bashrc 配置文件中,给 man 增加漂亮的色彩高亮
export LESS_TERMCAP_mb=$'\E[1m\E[32m'
export LESS_TERMCAP_mh=$'\E[2m'
export LESS_TERMCAP_mr=$'\E[7m'
export LESS_TERMCAP_md=$'\E[1m\E[36m'
export LESS_TERMCAP_ZW=""
export LESS_TERMCAP_us=$'\E[4m\E[1m\E[37m'
export LESS_TERMCAP_me=$'\E(B\E[m'
export LESS_TERMCAP_ue=$'\E[24m\E(B\E[m'
export LESS_TERMCAP_ZO=""
export LESS_TERMCAP_ZN=""
export LESS_TERMCAP_se=$'\E[27m\E(B\E[m'
export LESS_TERMCAP_ZV=""
export LESS_TERMCAP_so=$'\E[1m\E[33m\E[44m'

# ALT+hjkl/HJKL 快速移动光标,将下面内容添加到 ~/.inputrc 中可作用所有工具,
# 包括 bash/zsh/python/lua 等使用 readline 的工具,帮助见:info rluserman
"\eh": backward-char
"\el": forward-char
"\ej": next-history
"\ek": previous-history
"\eH": backward-word
"\eL": forward-word
"\eJ": beginning-of-line
"\eK": end-of-line


##############################################################################
# References
##############################################################################

https://github.com/Idnan/bash-guide
http://www.linuxstall.com/linux-command-line-tips-that-every-linux-user-should-know/
https://ss64.com/bash/syntax-keyboard.html
http://wiki.bash-hackers.org/commands/classictest
https://www.ibm.com/developerworks/library/l-bash-test/index.html
https://www.cyberciti.biz/faq/bash-loop-over-file/
https://linuxconfig.org/bash-scripting-tutorial
https://github.com/LeCoupa/awesome-cheatsheets/blob/master/languages/bash.sh
https://devhints.io/bash
https://github.com/jlevy/the-art-of-command-line
https://yq.aliyun.com/articles/68541

# vim: set ts=4 sw=4 tw=0 et :

# Go

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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
/*******************************************************************************
* Golang CHEATSHEET (中文速查表) - by chlins (created on 2018/02/14)
* Version: 3, Last Modified: 2018/03/07 19:51
* https://github.com/skywind3000/awesome-cheatsheets
******************************************************************************/



/******************************************************************************
* Go 编译器命令
*****************************************************************************/
go command [arguments] // go 命令 [参数]
go build // 编译包和依赖包
go clean // 移除对象和缓存文件
go doc // 显示包的文档
go env // 打印go的环境变量信息
go bug // 报告bug
go fix // 更新包使用新的api
go fmt // 格式规范化代码
go generate // 通过处理资源生成go文件
go get // 下载并安装包及其依赖
go install // 编译和安装包及其依赖
go list // 列出所有包
go run // 编译和运行go程序
go test // 测试
go tool // 运行给定的go工具
go version // 显示go当前版本
go vet // 发现代码中可能的错误



/*******************************************************************************
* Hello World
******************************************************************************/
// main.go
package main // 包名

import "fmt" // 导入fmt包

func main() { // 主函数
fmt.Println("Hello World") // 打印输出
}
// go run main.go // 直接运行
// go build && ./main // 先编译成二进制文件再运行



/*******************************************************************************
* 操作符
******************************************************************************/
// 算数操作符
+ - * / % // 加 减 乘 除 取余
& | ^ &^ // 位与 位或 位异或 位与非
<< >> // 左移 右移
// 比较操作
== != // 等于 不等于
< <= // 小于 小于等于
> >= // 大于 大于等于
// 逻辑操作
&& || ! // 逻辑与 逻辑或 逻辑非
// 其他
& * <- // 地址 指针引用 通道操作



/*******************************************************************************
* 声明
******************************************************************************/
a := 1 // 直接给一个未声明的变量赋值
var b int // var 变量名 数据类型 来声明
var c float64
// 注意:使用var声明过的变量不可再使用 := 赋值
a = 2
const d = 1 // 常量




/*******************************************************************************
* 数据类型
******************************************************************************/
s := "hello" // 字符
a := 1 // int
b := 1.2 // float64
c := 1 + 5i // complex128
// 数组
arr1 := [3]int{4, 5, 6} // 手动指定长度
arr2 := [...]int{1, 2, 3} // 由golang自动计算长度
// 切片
sliceInt := []int{1, 2} // 不指定长度
sliceByte := []byte("hello")
// 指针
a := 1
point := &a // 将a的地址赋给point


/*******************************************************************************
* 流程控制
******************************************************************************/
// for
i := 10
for i > 0 {
println(i--)
}
// if else
if i == 10 {
println("i == 10")
} else {
println("i != 10")
}
// switch
switch i {
case 10:
println("i == 10")
default:
println("i != 10")
}


/*******************************************************************************
* 函数
******************************************************************************/
// 以func关键字声明
func test() {}

f := func() {println("Lambdas function")} // 匿名函数
f()

func get() (a,b string) { // 函数多返回值
return "a", "b"
}
a, b := get()




/*******************************************************************************
* 结构体
******************************************************************************/
// golang中没有class只有struct
type People struct {
Age int // 大写开头的变量在包外可以访问
name string // 小写开头的变量仅可在本包内访问
}
p1 := People{25, "Kaven"} // 必须按照结构体内部定义的顺序
p2 := People{name: "Kaven", age: 25} // 若不按顺序则需要指定字段

// 也可以先不赋值
p3 := new(People)
p3.Age = 25
p3.name = "Kaven"


/*******************************************************************************
* 方法
******************************************************************************/
// 方法通常是针对一个结构体来说的
type Foo struct {
a int
}
// 值接收者
func (f Foo) test() {
f.a = 1 // 不会改变原来的值
}
// 指针接收者
func (f *Foo) test() {
f.a = 1 // 会改变原值
}



/*******************************************************************************
* go 协程
******************************************************************************/
go func() {
time.Sleep(10 * time.Second)
println("hello")
}() // 不会阻塞代码的运行 代码会直接向下运行
// channel 通道
c := make(chan int)
// 两个协程间可以通过chan通信
go func() {c <- 1}() // 此时c会被阻塞 直到值被取走前都不可在塞入新值
go func() {println(<-c)}()
// 带缓存的channel
bc := make(chan int, 2)
go func() {c <- 1; c <-2}() // c中可以存储声明时所定义的缓存大小的数据,这里是2个
go func() {println(<-c)}()



/*******************************************************************************
* 接口
******************************************************************************/
// go的接口为鸭子类型,即只要你实现了接口中的方法就实现了该接口
type Reader interface {
Reading() // 仅需实现Reading方法就实现了该接口
}

type As struct {}
func (a As) Reading() {} // 实现了Reader接口

type Bs struct {}
func (b Bs) Reading() {} // 也实现了Reader接口
func (b Bs) Closing() {}




/*******************************************************************************
* 一些推荐
******************************************************************************/
// 入门书籍
《Go学习笔记》 // 雨痕的
《Go语言实战》 // 强烈推荐
// 网上资料
https://github.com/astaxie/build-web-application-with-golang // 谢大的
https://github.com/Unknwon/the-way-to-go_ZH_CN // 无闻
https://github.com/Unknwon/go-fundamental-programming // 无闻教学视频
// 第三方类库
https://golanglibs.com/
// 大杂烩
https://github.com/avelino/awesome-go



/*******************************************************************************
* References
******************************************************************************/
https://github.com/a8m/go-lang-cheat-sheet
https://github.com/LeCoupa/awesome-cheatsheets

# Python

===

  • 本手册是 Python cheat sheet 的中文翻译版。原作者:Arianne Colton and Sean Chen (data.scientist.info@gmail.com)

# 常规

  • Python 对大小写敏感
  • Python 的索引从 0 开始
  • Python 使用空白符(制表符或空格)来缩进代码,而不是使用花括号

# 获取帮助

  • 获取主页帮助: help()
  • 获取函数帮助: help(str.replace)
  • 获取模块帮助: help(re)

# 模块 (库)

Python 的模块只是一个简单地以 .py 为后缀的文件。

  • 列出模块内容: dir(module1)
  • 导入模块: import module
  • 调用模块中的函数: module1.func1()

import 语句会创建一个新的命名空间 (namespace),并且在该命名空间内执行 .py 文件中的所有语句。如果你想把模块内容导入到当前命名空间,请使用 from module1 import * 语句。

# 数值类类型

查看变量的数据类型: type(variable)

# 六种经常使用的数据类型

  1. int/long:过大的 int 类型会被自动转化为 long 类型

  2. float:64 位,Python 中没有 double 类型

  3. bool:真或假

  4. str:在 Python 2 中默认以 ASCII 编码,而在 Python 3 中默认以 Unicode 编码

    • 字符串可置于单 / 双 / 三引号中

    • 字符串是字符的序列,因此可以像处理其他序列一样处理字符串

    • 特殊字符可通过 \ 或者前缀 r 实现:

      1
      str1 = r'this\f?ff'
    • 字符串可通过多种方式格式化:

      1
      2
      template = '%.2f %s haha $%d';
      str1 = template % (4.88, 'hola', 2)
  5. NoneType(None):Python “null” 值( None 对象存在一个实例)

    • None 不是一个保留关键字,而是 NoneType 的一个唯一实例

    • None 通常是可选函数参数的默认值:

      1
      def func1(a, b, c=None)
    • None 的常见用法:

      1
      if variable is None :
  6. datetime:Python 内置的 datetime 模块提供了 datetimedata 以及 time 类型。

    • datetime 组合了存储于 datetime 中的信息
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    # 从字符串中创建 datetime
    dt1 = datetime.strptime('20091031', '%Y%m%d')
    # 获取 date 对象
    dt1.date()
    # 获取 time 对象
    dt1.time()
    # 将 datetime 格式化为字符串
    dt1.strftime('%m/%d/%Y%H:%M')
    # 更改字段值
    dt2 = dt1.replace(minute=0, second=30)
    # 做差, diff 是一个 datetime.timedelta 对象
    diff = dt1 - dt2

  • strboolintfloat 同时也是显式类型转换函数。
  • 除字符串和元组外,Python 中的绝大多数对象都是可变的。

# 数据结构

:所有的 “非只读 (non-Get)” 函数调用,比如下面例子中的 list1.sort() ,除非特别声明,都是原地操作 (不会创建新的对象)。

# 元组

元组是 Python 中任何类型的对象的一个一维、固定长度、不可变的序列。

1
2
3
4
5
6
7
8
9
10
11
# 创建元组
tup1 = 4, 5, 6
tup1 = (6, 7, 8)
# 创建嵌套元组
tup1 = (4, 5, 6), (7, 8)
# 将序列或迭代器转化为元组
tuple([1, 0, 2])
# 连接元组
tup1 + tup2
# 解包元组
a, b, c = tup1

元组应用

1
2
# 交换两个变量的值
a, b = b, a

# 列表

列表是 Python 中任何类型的对象的一个一维、非固定长度、可变(比如内容可以被修改)的序列。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 创建列表
list1 = [1, 'a', 3]
list1 = list(tup1)
# 连接列表
list1 + list2
list1.extend(list2)
# 追加到列表的末尾
list1.append('b')
# 插入指定位置
list1.insert(PosIndex, 'a')
# 反向插入,即弹出给定位置的值/删除
ValueAtIdx = list1.pop(PosIndex)
# 移除列表中的第一个值, a 必须是列表中第一个值
list1.remove('a')
# 检查成员
3 in list1 => True or False
# 对列表进行排序
list1.sort()
# 按特定方式排序
list1.sort(key=len) # 按长度排序
  • 使用 + 连接列表会有比较大的开支,因为这个过程中会创建一个新的列表,然后复制对象。因此,使用 extend() 是更明智的选择。
  • insertappend 相比会有更大的开支(时间 / 空间)。
  • 在列表中检查是否包含一个值会比在字典和集合中慢很多,因为前者需要进行线性扫描,而后者是基于哈希表的,所以只需要花费常数时间。

# 内置的 bisect 模块

  • 对一个排序好的列表进行二分查找或插入

  • bisect.bisect 找到元素在列表中的位置, bisect.insort 将元素插入到相应位置。

  • 用法:

    1
    2
    3
    4
    5
    6
    import bisect
    list1 = list(range(10))
    #找到 5 在 list1 中的位置,从 1 开始,因此 position = index + 1
    bisect.bisect(list1, 5)
    #将 3.5 插入 list1 中合适位置
    bisect.insort(list1, 3.5)

bisect 模块中的函数并不会去检查列表是否排序好,因为这会花费很多时间。所以,对未排序好的列表使用这些函数也不会报错,但可能会返回不正确的结果。

# 针对序列类型的切片

序列类型包括 strarraytuplelist 等。

用法:

1
2
3
list1[start:stop]
# 如果使用 step
list1[start:stop:step]

  • 切片结果包含 start 索引,但不包含 stop 索引
  • start/stop 索引可以省略,如果省略,则默认为序列从开始到结束,如 list1 == list1[:]

step 的应用:

1
2
3
4
# 取出奇数位置的元素
list1[::2]
# 反转字符串
str1[::-1]

# 字典(哈希表)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 创建字典
dict1 = {'key1': 'value1', 2: [3, 2]}
# 从序列创建字典
dict(zip(KeyList, ValueList))
# 获取/设置/插入元素
dict1['key1']
dict1['key1'] = 'NewValue'
# get 提供默认值
dict1.get('key1', DefaultValue)
# 检查键是否存在
'key1' in dict1
# 获取键列表
dict1.keys()
# 获取值列表
dict1.values()
# 更新值
dict1.update(dict2) # dict1 的值被 dict2 替换
  • 如果键不存在,则会出现 KeyError Exception
  • 当键不存在时,如果 get() 不提供默认值则会返回 None
  • 以相同的顺序返回键列表和值列表,但顺序不是特定的,也就是说极大可能非排序。

# 有效字典键类型

  • 键必须是不可变的,比如标量类型 ( intfloatstring ) 或者元组(元组中的所有对象也必须是不可变的)。
  • 这儿涉及的技术术语是 “可哈希 (hashability)”。可以用函数 hash() 来检查一个对象是否是可哈希的,比如 hash('This is a string') 会返回一个哈希值,而 hash([1,2]) 则会报错(不可哈希)。

# 集合

  • 一个集合是一些无序且唯一的元素的聚集;

  • 你可以把它看成只有键的字典;

    1
    2
    3
    4
    5
    6
    7
    8
    9
    # 创建集合
    set([3, 6, 3])
    {3, 6, 3}
    # 子集测试
    set1.issubset(set2)
    # 超集测试
    set1.issuperset(set2)
    # 测试两个集合中的元素是否完全相同
    set1 == set2
  • 集合操作

    • 并(或): set1 | set2
    • 交(与): set1 & set2
    • 差: set1 - set2
    • 对称差(异或): set1 ^ set2

# 函数

Python 的函数参数传递是通过引用传递

  • 基本形式

    1
    def func1(posArg1, keywordArg1=1, ..)

    • 关键字参数必须跟在位置参数的后面;
    • 默认情况下,Python 不会 “延迟求值”,表达式的值会立刻求出来。
  • 函数调用机制

    1. 所有函数均位于模块内部作用域。见 “模块” 部分。
    2. 在调用函数时,参数被打包成一个元组和一个字典,函数接收一个元组 args 和一个字典 kwargs ,然后在函数内部解包。
  • “函数是对象” 的常见用法:

    1
    2
    3
    def func1(ops = [str.strip, user_define_func, ..], ..):
    for function in ops:
    value = function(value)

# 返回值

  • 如果函数直到结束都没有 return 语句,则返回 None

  • 如果有多个返回值则通过一个元组来实现。

    1
    2
    return (value1, value2)
    value1, value2 = func1(..)

# 匿名函数(又称 LAMBDA 函数)

  • 什么是匿名函数?

    匿名函数是一个只包含一条语句的简单函数。

    1
    2
    lambda x : x * 2
    # def func1(x) : return x * 2
  • 匿名函数的应用:“柯里化 (curring)”,即利用已存在函数的部分参数来派生新的函数。

    1
    ma60 = lambda x : pd.rolling_mean(x, 60)

# 一些有用的函数(针对数据结构)

  1. Enumerate 返回一个序列 (i, value) 元组, i 是当前 item 的索引。

    1
    for i, value in enumerate(collection):
    • 应用:创建一个序列中值与其在序列中的位置的字典映射(假设每一个值都是唯一的)。
  2. Sorted 可以从任意序列中返回一个排序好的序列。

    1
    sorted([2, 1, 3]) => [1, 2, 3]
    • 应用:

      1
      2
      sorted(set('abc bcd')) => [' ', 'a', 'b', 'c', 'd']
      # 返回一个字符串排序后无重复的字母序列
  3. Zip 函数可以把许多列表、元组或其他序列的元素配对起来创建一系列的元组。

    1
    zip(seq1, seq2) => [('seq1_1', 'seq2_1'), (..), ..]
    • zip() 可以接收任意数量的序列作为参数,但是产生的元素的数目取决于最短的序列。

    • 应用:多个序列同时迭代:

      1
      for i, (a, b) in enumerate(zip(seq1, seq2)):
    • unzip :另一种思考方式是把一些行转化为一些列:

      1
      seq1, seq2 = unzip(zipOutput)
  4. Reversed 将一个序列的元素以逆序迭代。

    1
    list(reversed(range(10)))

    reversed() 会返回一个迭代器, list() 使之成为一个列表。

# 控制流

  1. 用于 if-else 条件中的操作符:

    1
    2
    3
    4
    5
    var1 is var2  # 检查两个变量是否是相同的对象

    var1 is not var2 # 检查两个变量是否是不同的对象

    var1 == var2 # 检查两个变量的值是否相等

    :Python 中使用 andornot 来组合条件,而不是使用 &&||!

  2. for 循环的常见用法:

    1
    2
    3
    4
    5
    for element in iterator:  # 可迭代对象(list、tuple)或迭代器
    pass

    for a, b, c in iterator: # 如果元素是可以解包的序列
    pass
  3. pass :无操作语句,在不需要进行任何操作的块中使用。

  4. 三元表达式,又称简洁的 if-else ,基本形式:

    1
    value = true-expr if condition else false-expr
  5. Python 中没有 switch/case 语句,请使用 if/elif

# 面向对象编程

  1. 对象是 Python 中所有类型的根。

  2. 万物(数字、字符串、函数、类、模块等)皆为对象,每个对象均有一个 “类型 (type)”。对象变量是一个指向变量在内存中位置的指针。

  3. 所有对象均会被引用计数

    1
    2
    3
    4
    5
    6
    sys.getrefcount(5) => x
    a = 5, b = a
    # 上式会在等号的右边创建一个对象的引用,因此 a 和 b 均指向 5
    sys.getrefcount(5)
    => x + 2
    del(a); sys.getrefcount(5) => x + 1
  4. 类的基本形式:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class MyObject(object):
    # 'self' 等价于 Java/C++ 中的 'this'
    def __init__(self, name):
    self.name = name
    def memberFunc1(self, arg1):
    pass
    @staticmethod
    def classFunc2(arg1):
    pass
    obj1 = MyObject('name1')
    obj1.memberFunc1('a')
    MyObject.classFunc2('b')
  5. 有用的交互式工具:

    1
    dir(variable1)  # 列出对象的所有可用方法

# 常见字符串操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 通过分隔符连接列表/元组
', '.join([ 'v1', 'v2', 'v3']) => 'v1, v2, v3'

# 格式化字符串
string1 = 'My name is {0} {name}'
newString1 = string1.format('Sean', name = 'Chen')

# 分裂字符串
sep = '-';
stringList1 = string1.split(sep)

# 获取子串
start = 1;
string1[start:8]

# 补 '0' 向右对齐字符串
month = '5';
month.zfill(2) => '05'
month = '12';
month.zfill(2) => '12'
month.zfill(3) => '012'

# 异常处理

  1. 基本形式:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    try:
    pass
    except ValueError as e:
    print e
    except (TypeError, AnotherError):
    pass
    except:
    pass
    finally:
    pass # 清理,比如 close db;
  2. 手动引发异常:

    1
    2
    3
    4
    raise AssertionError  # 断言失败
    raise SystemExit
    # 请求程序退出
    raise RuntimeError('错误信息 :..')

# 列表、字典以及元组的推导表达式

使代码更加易读易写的语法糖。

  1. 列表推导

    • 用一个简练的表达式,通过筛选一个数据集并且转换经过筛选的元素的方式来简明地生成新列表。

    • 基本形式:

      1
      [expr for val in collection if condition]

    等价于

    1
    2
    3
    4
    result = []
    for val in collection:
    if condition:
    result.append(expr)

    可以省略过滤条件,只留下表达式。

  2. 字典推导

    • 基本形式:

      1
      {key-expr : value-expr for value in collection if condition}
  3. 集合推导

    • 基本形式:和列表推导一样,不过是用 () 而不是 []
  4. 嵌套列表

    • 基本形式:

      1
      [expr for val in collection for innerVal in val if condition]

# 单元测试

Python 自带 unittest 模块,可供我们编写单元测试。

1
import unittest

我们可以编写继承于 unittest.TestCase 测试类的子类,并在子类中编写具体的测试函数。测试函数命必须以 test_ 开头,否则不会被识别为测试函数,进而不会在运行单元测试时被运行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class TestSubclass(unittest.TestCase):

def test_func(self):
self.assertEqual(0, 0)
# 可以通过msg关键字参数提供测试失败时的提示消息
self.assertEqual(0, 0, msg='modified message')
self.assertGreater(1, 0)
self.assertIn(0, [0])
self.assertTrue(True)
# 测试是否会抛出异常
with self.assertRaises(KeyError):
_ = dict()[1]

# 被@unittest.skip装饰器装饰的测试类或测试函数会被跳过
@unittest.skip(reason='just skip')
def test_skip(self):
raise Exception('I shall never be tested')

另外, unittest.TestCase 中还有两个特殊的成员函数,他们分别会在调用每一个测试函数的前后运行。在测试前连接数据库并在测试完成后断开连接是一种常见的使用场景。

1
2
3
4
5
6
7
8
9
10
11
def setUp(self):
# To do: connect to the database
pass

def tearDown(self):
# To do: release the connection
pass

def test_database(self):
# To do: test the database
pass

测试类编写完毕后,可以通过添加以下代码来将当前文件当成正常的 Python 脚本使用

1
2
if __name__ == '__main__':
unittest.main()

# Git

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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
##############################################################################
# 配置
##############################################################################
git config --global "Your Name"
git config --global "Email Address"


##############################################################################
# 初始化
##############################################################################
git init


##############################################################################
# 提交修改
##############################################################################
git add <file>
git add -u 提交work directory中所有已track的文件至staging area
git commit -m "descriptions"
git commit --amend 对最近一次的提交做内容修改
git commit --amend --author "user_name <user_email>" 修改最近提交用户名和邮箱


##############################################################################
# 查看状态、比对
##############################################################################
git status
git status -s 文件状态缩略信息, 常见 A:新增; M:文件变更; ?:未track; D:删除
git diff <file>
git diff HEAD -- <file> 查看工作区和版本库里面最新版本的区别
git diff --check <file> 检查是否有空白错误(regex:' \{1,\}$')
git diff --cached <file> 查看已add的内容(绿M)

##############################################################################
# 查看历史版本、历史操作
##############################################################################
git log
git reflog
git log -n 最近n条的提交历史
git log <branch_name> -n 分支branch_name最近n条的提交历史
git log --stat 历次commit的文件变化
git log lhs_hash..rhs_hash 对比两次commit的变化(增删的主语为lhs, 如git log HEAD~2..HEAD == git log HEAD -3)
git log -p 历次commit的内容增删
git log -p -W 历次commit的内容增删, 同时显示变更内容的上下文
git log origin/EI-1024 -1 --stat -p -W 查看远端分支EI-1024前一次修改的详细内容
git log origin/master..dev --stat -p -W 查看本地dev分支比远端master分支变化(修改)的详细内容

git log <branch_name> --oneline 对提交历史单行排列
git log <branch_name> --graph 对提交历史图形化排列
git log <branch_name> --decorate 对提交历史关联相关引用, 如tag, 本地远程分支等
git log <branch_name> --oneline --graph --decorate 拼接一下, 树形化显示历史
git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen%ai(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit 同上, 建议alais保存

git log --since --after 显示时间之后的提交
git log --until --before 显示时间之前的提交
git --author 显示指定作者的提交
git --committer 显示指定committer的提交(注:committer不一定是author)
git log origin/b3.3/master --author=yx-ren --since="2019-10-01" --before="2019-11-01" 查看某作者在某发布版本最近一个月的提交, 常见于线上背锅
git log origin/b3.0/master --author=some_leave --since="1 month ago" 查看某刚离职同事过去一个月的提交, 常见于背锅
git log --since=1.weeks 过去一周的提交(写周报的时候可以看看我这一周干了啥)
git log --since=1.days 过去一天的提交(下班的时候可以看看我这一天干了啥)
git log --since="1 weeks 2 days 3 hours 40 minutes 50 seconds ago" 过去1周2天3小时40分50秒之内的提交


##############################################################################
# 版本回退、前进
##############################################################################
git reset --hard HEAD^ 回退到上1版本
git reset --hard HEAD~5 回退到上5个版本
git reset --hard id 回退到指定版本


##############################################################################
# 撤销修改
##############################################################################
git checkout -- <file> 撤销修改:误修改工作区文件,未git add/commit
git restore <file> 撤销修改:误修改工作区文件,未git add/commit
git reset HEAD <file> 撤销git add:误将文件加入暂存区(git add),未git commit
git reset --hard HEAD^ 撤销git commit:误将文件提交(一旦提交,只能通过版本回退进行撤销)


##############################################################################
# 删除与恢复
##############################################################################
git rm/add <file>
git commit -m "remove <file>" 删除版本库中的<file>:删除工作区文件后,继续删除版本库中相应的文件
git checkout -- <file> 根据版本库中的<file>恢复工作区<file>


##############################################################################
# 关联GitHub远程仓库(本地到远程)
##############################################################################
git remote add origin <remote address> 在本地工作区目录下按照 GitHub 提示进行关联
git remote rm origin 解除错误关联
git push -u origin master 第一次将本地仓库推送至远程仓库(每次在本地提交后进行操作)
git push origin master 以后每次将本地仓库推送至远程仓库(每次在本地提交后进行操作)
<remote address>:
git@github.com:<username>/<repository>.git
https://github.com/<username>/<repository>.git


##############################################################################
# 克隆GitHub远程仓库(远程到本地)
##############################################################################
git clone <remote address> git协议速度更快但通常公司内网不允许,https协议速度慢


##############################################################################
# 分支管理:创建、切换、查看、合并、删除
##############################################################################
git branch <branch name> 创建<branch name>分支
git checkout <branch name> 切换至<branch name>分支
git switch <branch name> 切换至<branch name>分支
git checkout -b <branch name> 创建并切换至<branch name>分支
git switch -c <branch name> 创建并切换至<branch name>分支
git branch 查看已有分支(* 表示当前分支)
git merge <branch name> 合并<branch name>到当前分支(通常在master分支下操作)
git branch -d <branch name> 删除分支


##############################################################################
# 解决合并冲突
##############################################################################
合并时报错“分支发生冲突”,首先vim相应文件,修改冲突位置,然后按照git add/commit重新提交,最后删除多余分支即可。
git log --graph --pretty=oneline --abbrev-commit
git log --graph


##############################################################################
# 分支管理:合并后删除分支也在 log 中保留分支记录
##############################################################################
git merge --no-ff -m "descriptions" <branch name>


##############################################################################
# 开发流程:
##############################################################################
master分支 发布稳定版本
dev分支 发布开发版本
<developer name>分支 个人开发分支(个人开发完成将该分支并入dev,同时保留该分支,继续开发)


##############################################################################
# Bug分支管理(建立单独分支进行bug修复)
##############################################################################
软件开发中,bug就像家常便饭一样。有了bug就需要修复,在Git中,由于分支是如此的强大,所以,每个bug都可以通过一个新的临时分支来修复,修复后,合并分支,然后将临时分支删除。
git stash 保存当前工作现场(在dev未完成开发,但master有bug需要修复)
git stash pop 回到dev分支后恢复工作现场(list中的现场会同时被删除)
git stash list 查看当前存储的工作现场
git stash apply stash@{#} 回到指定工作现场(list中的现场不会被删除,需要用git stash drop)
git stash drop stash@{#} 删除指定工作现场
git cherry-pick <id> 在master修复好bug后,在dev复制一遍bug修复流程


##############################################################################
# Feature分支管理(建立单独分支添加新功能)
##############################################################################
软件开发中,总有无穷无尽的新的功能要不断添加进来。添加一个新功能时,你肯定不希望因为一些实验性质的代码,把主分支搞乱了,所以,每添加一个新功能,最好新建一个feature分支,在上面开发,完成后,合并,最后,删除该feature分支。
git branch -D <branch name> 强制删除分支(丢弃未合并分支)


##############################################################################
# 协作与分支推送
##############################################################################
User 1:
git remote [-v] 查看远程库信息(-v 查看详细信息)
git push origin [master/dev/...] 推送指定分支到远程
User 2:
git clone <remote address> 克隆到本地(只能克隆master)
git checkout -b dev origin/dev 本地新建分支并关联远程
git add/commit/push 添加、提交、推送更新
User 1:
git add/commit/push 推送时报错(与user 2推送的更新冲突)
git pull <remote> <branch>
git branch --set-upstream-to=origin/<branch> <branch> 本地与远程关联
git pull 拉取远程文件(并解决冲突)
git commit/push 重新提交并推送


##############################################################################
# 标签管理(常用于版本管理):查看、创建、操作
##############################################################################
git tag 查看标签
git show <tag name> 查看指定标签
git log --pretty=oneline --abbrev-commit --decorate=full 在log中显示标签
git tag <tag name> 为上次commit位置打标签
git tag <tag name> <commit id> 为指定commit位置打标签
git tag -a <tag name> -m "descriptions" <commit id> 为指定commit打标并添加描述
git tag -d <tag name> 删除本地标签
git push origin <tag name> 推送指定标签到远程
git push origin --tags 推送所有本地标签到远程
git push origin :refs/tags/<tag name> 删除远程标签(先删除本地标签)

##############################################################################
# rebase(换基)
##############################################################################
# rebase 在日常中常用功能主要是两个, 多人协同开发定期rebase master以及压缩某分支多个commit
git rebase master 常见于多人开发, 每个开发人员从master checkout出自己的分支, 开发一段时间后提交至master之前最好rebase一下, 防止冲突,
就算真有冲突在本地解决好过强制提交, 开发流程中尽量保证master的干净整洁
git rebase -i HEAD~n 压缩当前分支的n个commit并合并为1个commit, 常见第一行为pick, 剩下的n-1行为squash

git rebase --abort # rebase过程中发生错误, 可以利用该命令终止整个rebase过程
git rebase --continue # rebase过程中发生冲突, 在解决冲突后可以利用该命令进行后续过程

##############################################################################
# 打patch(补丁)
##############################################################################
# 生成diff patch文件(git可以识别diff文件)
git <branch> log -n -p > diff.patch # 生成某分支过去n个commit的文件diff信息至单个diff文件
git diff <--cached> diff.patch # 针对当前缓存区的内容生成diff文件

# 利用apply打patch
git apply --check diff.patch #检查是否可以正常应用, 无回显证明无冲突
git apply --stat diff.patch #查看应用diff文件后的文件变化
git apply diff.patch #打patch, 仅仅改变文件信息, 无commit信息, 仍然需要add, commit

# 利用--format-patch生成patch, 带commit信息
git format-patch <branch> -n   #生成分支<branch>最近的n次commit的patch
git format-patch <r1>..<r2> #生成两个commit间的修改的patch(包含两个commit. <r1>和<r2>都是具体的commit号)
git format-patch -1 <r1> #生成单个commit的patch
git format-patch <r1> #生成某commit以来的修改patch(不包含该commit)
git format-patch --root <r1>  #生成从根到r1提交的所有patch

# 利用am打patch
git apply --check 0001-update-bash.sh.patch #检查patch是否冲突可用
git apply --stat 0001-update-bash.sh.patch #检查patch文件变更情况, 无回显证明无冲突
git am 0001-update-bash.sh.patch #将该patch打上到当前分支, 带commit信息
git am ./*.patch #将当前路径下的所有patch按照先后顺序打上
git am --abort #终止整个打patch的过程, 类似rebase --abort
git am --resolved #解决冲突后, 可以执行该命令进行后续的patch, 类似rebase --continue

##############################################################################

##############################################################################
# 使用GitHub
##############################################################################
fork --> clone --> add/commit/push --> pull request


##############################################################################
# 其他配置
##############################################################################
git config --global color.ui true 显示颜色


##############################################################################
# 配置.gitignore文件
##############################################################################
/<dir name>/ 忽略文件夹
*.zip 忽略.zip文件
/<dir name>/<file name> 忽略指定文件


##############################################################################
# 文件.gitignore生效后
##############################################################################
git add -f <file> 强制添加
git check-ignore -v <file> 查看生效规则


##############################################################################
# 配置别名
##############################################################################
git config [--global] alias.<alias> '<original command>' 为所有工作区/当前工作区配置别名
.git/config 当前工作区的配置文件
~/.gitconfig 当前用户的配置文件


##############################################################################
# References
##############################################################################
https://www.liaoxuefeng.com/wiki/896043488029600
Edited on Views times