bash.sh 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886
  1. ##############################################################################
  2. # BASH CHEATSHEET (中文速查表) - by skywind (created on 2018/02/14)
  3. # Version: 47, Last Modified: 2019/09/24 17:58
  4. # https://github.com/skywind3000/awesome-cheatsheets
  5. ##############################################################################
  6. ##############################################################################
  7. # 常用快捷键(默认使用 Emacs 键位)
  8. ##############################################################################
  9. CTRL+A # 移动到行首,同 <Home>
  10. CTRL+B # 向后移动,同 <Left>
  11. CTRL+C # 结束当前命令
  12. CTRL+D # 删除光标前的字符,同 <Delete> ,或者没有内容时,退出会话
  13. CTRL+E # 移动到行末,同 <End>
  14. CTRL+F # 向前移动,同 <Right>
  15. CTRL+G # 退出当前编辑(比如正在 CTRL+R 搜索历史时)
  16. CTRL+H # 删除光标左边的字符,同 <Backspace>
  17. CTRL+K # 删除光标位置到行末的内容
  18. CTRL+L # 清屏并重新显示
  19. CTRL+N # 移动到命令历史的下一行,同 <Down>
  20. CTRL+O # 类似回车,但是会显示下一行历史
  21. CTRL+P # 移动到命令历史的上一行,同 <Up>
  22. CTRL+R # 历史命令反向搜索,使用 CTRL+G 退出搜索
  23. CTRL+S # 历史命令正向搜索,使用 CTRL+G 退出搜索
  24. CTRL+T # 交换前后两个字符
  25. CTRL+U # 删除字符到行首
  26. CTRL+V # 输入字符字面量,先按 CTRL+V 再按任意键
  27. CTRL+W # 删除光标左边的一个单词
  28. CTRL+X # 列出可能的补全
  29. CTRL+Y # 粘贴前面 CTRL+u/k/w 删除过的内容
  30. CTRL+Z # 暂停前台进程返回 bash,需要时可用 fg 将其切换回前台
  31. CTRL+_ # 撤销(undo),有的终端将 CTRL+_ 映射为 CTRL+/ 或 CTRL+7
  32. ALT+b # 向后(左边)移动一个单词
  33. ALT+d # 删除光标后(右边)一个单词
  34. ALT+f # 向前(右边)移动一个单词
  35. ALT+t # 交换字符
  36. ALT+BACKSPACE # 删除光标前面一个单词,类似 CTRL+W,但不影响剪贴板
  37. CTRL+X CTRL+X # 连续按两次 CTRL+X,光标在当前位置和行首来回跳转
  38. CTRL+X CTRL+E # 用你指定的编辑器,编辑当前命令
  39. ##############################################################################
  40. # BASH 基本操作
  41. ##############################################################################
  42. exit # 退出当前登录
  43. env # 显示环境变量
  44. echo $SHELL # 显示你在使用什么 SHELL
  45. bash # 使用 bash,用 exit 返回
  46. which bash # 搜索 $PATH,查找哪个程序对应命令 bash
  47. whereis bash # 搜索可执行,头文件和帮助信息的位置,使用系统内建数据库
  48. whatis bash # 查看某个命令的解释,一句话告诉你这是干什么的
  49. clear # 清初屏幕内容
  50. reset # 重置终端(当你不小心 cat 了一个二进制,终端状态乱掉时使用)
  51. ##############################################################################
  52. # 目录操作
  53. ##############################################################################
  54. cd # 返回自己 $HOME 目录
  55. cd {dirname} # 进入目录
  56. pwd # 显示当前所在目录
  57. mkdir {dirname} # 创建目录
  58. mkdir -p {dirname} # 递归创建目录
  59. pushd {dirname} # 目录压栈并进入新目录
  60. popd # 弹出并进入栈顶的目录
  61. dirs -v # 列出当前目录栈
  62. cd - # 回到之前的目录
  63. cd -{N} # 切换到目录栈中的第 N个目录,比如 cd -2 将切换到第二个
  64. ##############################################################################
  65. # 文件操作
  66. ##############################################################################
  67. ls # 显示当前目录内容,后面可接目录名:ls {dir} 显示指定目录
  68. ls -l # 列表方式显示目录内容,包括文件日期,大小,权限等信息
  69. ls -1 # 列表方式显示目录内容,只显示文件名称,减号后面是数字 1
  70. ls -a # 显示所有文件和目录,包括隐藏文件(.开头的文件/目录名)
  71. ln -s {fn} {link} # 给指定文件创建一个软链接
  72. cp {src} {dest} # 拷贝文件,cp -r dir1 dir2 可以递归拷贝(目录)
  73. rm {fn} # 删除文件,rm -r 递归删除目录,rm -f 强制删除
  74. mv {src} {dest} # 移动文件,如果 dest 是目录,则移动,是文件名则覆盖
  75. touch {fn} # 创建或者更新一下制定文件
  76. cat {fn} # 输出文件原始内容
  77. any_cmd > {fn} # 执行任意命令并将标准输出重定向到指定文件
  78. more {fn} # 逐屏显示某文件内容,空格翻页,q 退出
  79. less {fn} # 更高级点的 more,更多操作,q 退出
  80. head {fn} # 显示文件头部数行,可用 head -3 abc.txt 显示头三行
  81. tail {fn} # 显示文件尾部数行,可用 tail -3 abc.txt 显示尾部三行
  82. tail -f {fn} # 持续显示文件尾部数据,可用于监控日志
  83. nano {fn} # 使用 nano 编辑器编辑文件
  84. vim {fn} # 使用 vim 编辑文件
  85. diff {f1} {f2} # 比较两个文件的内容
  86. wc {fn} # 统计文件有多少行,多少个单词
  87. chmod 644 {fn} # 修改文件权限为 644,可以接 -R 对目录循环改权限
  88. chgrp group {fn} # 修改文件所属的用户组
  89. chown user1 {fn} # 修改文件所有人为 user1, chown user1:group1 fn 可以修改组
  90. file {fn} # 检测文件的类型和编码
  91. basename {fn} # 查看文件的名字(不包括路径)
  92. dirname {fn} # 查看文件的路径(不包括名字)
  93. grep {pat} {fn} # 在文件中查找出现过 pat 的内容
  94. grep -r {pat} . # 在当前目录下递归查找所有出现过 pat 的文件内容
  95. stat {fn} # 显示文件的详细信息
  96. ##############################################################################
  97. # 用户管理
  98. ##############################################################################
  99. whoami # 显示我的用户名
  100. who # 显示已登录用户信息,w / who / users 内容略有不同
  101. w # 显示已登录用户信息,w / who / users 内容略有不同
  102. users # 显示已登录用户信息,w / who / users 内容略有不同
  103. passwd # 修改密码,passwd {user} 可以用于 root 修改别人密码
  104. finger {user} # 显示某用户信息,包括 id, 名字, 登录状态等
  105. adduser {user} # 添加用户
  106. deluser {user} # 删除用户
  107. w # 查看谁在线
  108. su # 切换到 root 用户
  109. su - # 切换到 root 用户并登录(执行登录脚本)
  110. su {user} # 切换到某用户
  111. su -{user} # 切换到某用户并登录(执行登录脚本)
  112. id {user} # 查看用户的 uid,gid 以及所属其他用户组
  113. id -u {user} # 打印用户 uid
  114. id -g {user} # 打印用户 gid
  115. write {user} # 向某用户发送一句消息
  116. last # 显示最近用户登录列表
  117. last {user} # 显示登录记录
  118. lastb # 显示失败登录记录
  119. lastlog # 显示所有用户的最近登录记录
  120. sudo {command} # 以 root 权限执行某命令
  121. ##############################################################################
  122. # 进程管理
  123. ##############################################################################
  124. ps # 查看当前会话进程
  125. ps ax # 查看所有进程,类似 ps -e
  126. ps aux # 查看所有进程详细信息,类似 ps -ef
  127. ps auxww # 查看所有进程,并且显示进程的完整启动命令
  128. ps -u {user} # 查看某用户进程
  129. ps axjf # 列出进程树
  130. ps xjf -u {user} # 列出某用户的进程树
  131. ps -eo pid,user,command # 按用户指定的格式查看进程
  132. ps aux | grep httpd # 查看名为 httpd 的所有进程
  133. ps --ppid {pid} # 查看父进程为 pid 的所有进程
  134. pstree # 树形列出所有进程,pstree 默认一般不带,需安装
  135. pstree {user} # 进程树列出某用户的进程
  136. pstree -u # 树形列出所有进程以及所属用户
  137. pgrep {procname} # 搜索名字匹配的进程的 pid,比如 pgrep apache2
  138. kill {pid} # 结束进程
  139. kill -9 {pid} # 强制结束进程,9/SIGKILL 是强制不可捕获结束信号
  140. kill -KILL {pid} # 强制执行进程,kill -9 的另外一种写法
  141. kill -l # 查看所有信号
  142. kill -l TERM # 查看 TERM 信号的编号
  143. killall {procname} # 按名称结束所有进程
  144. pkill {procname} # 按名称结束进程,除名称外还可以有其他参数
  145. top # 查看最活跃的进程
  146. top -u {user} # 查看某用户最活跃的进程
  147. any_command & # 在后台运行某命令,也可用 CTRL+Z 将当前进程挂到后台
  148. jobs # 查看所有后台进程(jobs)
  149. bg # 查看后台进程,并切换过去
  150. fg # 切换后台进程到前台
  151. fg {job} # 切换特定后台进程到前台
  152. trap cmd sig1 sig2 # 在脚本中设置信号处理命令
  153. trap "" sig1 sig2 # 在脚本中屏蔽某信号
  154. trap - sig1 sig2 # 恢复默认信号处理行为
  155. nohup {command} # 长期运行某程序,在你退出登录都保持它运行
  156. nohup {command} & # 在后台长期运行某程序
  157. disown {PID|JID} # 将进程从后台任务列表(jobs)移除
  158. wait # 等待所有后台进程任务结束
  159. ##############################################################################
  160. # 常用命令:SSH / 系统信息 / 网络
  161. ##############################################################################
  162. ssh user@host # 以用户 user 登录到远程主机 host
  163. ssh -p {port} user@host # 指定端口登录主机
  164. ssh-copy-id user@host # 拷贝你的 ssh key 到远程主机,避免重复输入密码
  165. scp {fn} user@host:path # 拷贝文件到远程主机
  166. scp user@host:path dest # 从远程主机拷贝文件回来
  167. scp -P {port} ... # 指定端口远程拷贝文件
  168. uname -a # 查看内核版本等信息
  169. man {help} # 查看帮助
  170. man -k {keyword} # 查看哪些帮助文档里包含了该关键字
  171. info {help} # 查看 info pages,比 man 更强的帮助系统
  172. uptime # 查看系统启动时间
  173. date # 显示日期
  174. cal # 显示日历
  175. vmstat # 显示内存和 CPU 使用情况
  176. vmstat 10 # 每 10 秒打印一行内存和 CPU情况,CTRL+C 退出
  177. free # 显示内存和交换区使用情况
  178. df # 显示磁盘使用情况
  179. du # 显示当前目录占用,du . --max-depth=2 可以指定深度
  180. du -h # 显示当前目录占用,-h 以方便阅读的格式输出 (K/M/G)
  181. uname # 显示系统版本号
  182. hostname # 显示主机名称
  183. showkey -a # 查看终端发送的按键编码
  184. ping {host} # ping 远程主机并显示结果,CTRL+C 退出
  185. ping -c N {host} # ping 远程主机 N 次
  186. traceroute {host} # 侦测路由连通情况
  187. mtr {host} # 高级版本 traceroute
  188. host {domain} # DNS 查询,{domain} 前面可加 -a 查看详细信息
  189. whois {domain} # 取得域名 whois 信息
  190. dig {domain} # 取得域名 dns 信息
  191. route -n # 查看路由表
  192. netstat -a # 列出所有端口
  193. netstat -an # 查看所有连接信息,不解析域名
  194. netstat -anp # 查看所有连接信息,包含进程信息(需要 sudo)
  195. netstat -l # 查看所有监听的端口
  196. netstat -t # 查看所有 TCP 链接
  197. netstat -lntu # 显示所有正在监听的 TCP 和 UDP 信息
  198. netstat -lntup # 显示所有正在监听的 socket 及进程信息
  199. netstat -i # 显示网卡信息
  200. netstat -rn # 显示当前系统路由表,同 route -n
  201. ss -an # 比 netstat -an 更快速更详细
  202. ss -s # 统计 TCP 的 established, wait 等
  203. wget {url} # 下载文件,可加 --no-check-certificate 忽略 ssl 验证
  204. wget -qO- {url} # 下载文件并输出到标准输出(不保存)
  205. curl -sL {url} # 同 wget -qO- {url} 没有 wget 的时候使用
  206. sz {file} # 发送文件到终端,zmodem 协议
  207. rz # 接收终端发送过来的文件
  208. ##############################################################################
  209. # 变量操作
  210. ##############################################################################
  211. varname=value # 定义变量
  212. varname=value command # 定义子进程变量并执行子进程
  213. echo "$varname" # 查看变量内容
  214. echo $$ # 查看当前 shell 的进程号
  215. echo $! # 查看最近调用的后台任务进程号
  216. echo $? # 查看最近一条命令的返回码
  217. export VARNAME=value # 设置环境变量(将会影响到子进程)
  218. array[0]=valA # 定义数组
  219. array[1]=valB
  220. array[2]=valC
  221. array=([0]=valA [1]=valB [2]=valC) # 另一种方式
  222. array=(valA valB valC) # 另一种方式
  223. ${array[i]} # 取得数组中的元素
  224. ${#array[@]} # 取得数组的长度
  225. ${#array[i]} # 取得数组中某个变量的长度
  226. declare -a # 查看所有数组
  227. declare -f # 查看所有函数
  228. declare -F # 查看所有函数,仅显示函数名
  229. declare -i # 查看所有整数
  230. declare -r # 查看所有只读变量
  231. declare -x # 查看所有被导出成环境变量的东西
  232. declare -p varname # 输出变量是怎么定义的(类型+值)
  233. ${varname:-word} # 如果变量不为空则返回变量,否则返回 word
  234. ${varname:=word} # 如果变量不为空则返回变量,否则赋值成 word 并返回
  235. ${varname:?message} # 如果变量不为空则返回变量,否则打印错误信息并退出
  236. ${varname:+word} # 如果变量不为空则返回 word,否则返回 null
  237. ${varname:offset:len} # 取得字符串的子字符串
  238. ${variable#pattern} # 如果变量头部匹配 pattern,则删除最小匹配部分返回剩下的
  239. ${variable##pattern} # 如果变量头部匹配 pattern,则删除最大匹配部分返回剩下的
  240. ${variable%pattern} # 如果变量尾部匹配 pattern,则删除最小匹配部分返回剩下的
  241. ${variable%%pattern} # 如果变量尾部匹配 pattern,则删除最大匹配部分返回剩下的
  242. ${variable/pattern/str} # 将变量中第一个匹配 pattern 的替换成 str,并返回
  243. ${variable//pattern/str} # 将变量中所有匹配 pattern 的地方替换成 str 并返回
  244. ${#varname} # 返回字符串长度
  245. *(patternlist) # 零次或者多次匹配
  246. +(patternlist) # 一次或者多次匹配
  247. ?(patternlist) # 零次或者一次匹配
  248. @(patternlist) # 单词匹配
  249. !(patternlist) # 不匹配
  250. array=($text) # 按空格分隔 text 成数组,并赋值给变量
  251. IFS="/" array=($text) # 按斜杆分隔字符串 text 成数组,并赋值给变量
  252. text="${array[*]}" # 用空格链接数组并赋值给变量
  253. text=$(IFS=/; echo "${array[*]}") # 用斜杠链接数组并赋值给变量
  254. A=( foo bar "a b c" 42 ) # 数组定义
  255. B=("${A[@]:1:2}") # 数组切片:B=( bar "a b c" )
  256. C=("${A[@]:1}") # 数组切片:C=( bar "a b c" 42 )
  257. echo "${B[@]}" # bar a b c
  258. echo "${B[1]}" # a b c
  259. echo "${C[@]}" # bar a b c 42
  260. echo "${C[@]: -2:2}" # a b c 42 减号前的空格是必须的
  261. $(UNIX command) # 在 subshell 中运行命令 (不会改变当前 shell 的环境),并将标准输出内容捕获并返回
  262. varname=$(id -u user) # 将用户名为 user 的 uid 赋值给 varname 变量
  263. num=$(expr 1 + 2) # 兼容 posix sh 的计算,使用 expr 命令计算结果
  264. num=$(expr $num + 1) # 数字自增
  265. expr 2 \* \( 2 + 3 \) # 兼容 posix sh 的复杂计算,输出 10
  266. num=$[1 + 2] # 计算 1+2 赋值给 num,使用 bash 独有的 $[..] 计算
  267. num=$((1 + 2)) # 同上, 但该语法由 POSIX shell 指定
  268. num=$(($num + 1)) # 变量递增
  269. num=$((num + 1)) # 变量递增,双括号内的 $ 可以省略
  270. num=$((1 + (2 + 3) * 2)) # 复杂计算
  271. ##############################################################################
  272. # 事件指示符 (仅在交互式 shell 生效)
  273. ##############################################################################
  274. !! # 上一条命令
  275. !^ # 上一条命令的第一个单词
  276. !:n # 上一条命令的第n个单词
  277. !:n-$ # 上一条命令的第n个单词到最后一个单词
  278. !$ # 上一条命令的最后一个单词
  279. !-n:$ # 上n条命令的最后一个单词
  280. !string # 最近一条包含string的命令
  281. !^string1^string2 # 最近一条包含string1的命令, 快速替换string1为string2
  282. !# # 本条命令之前所有的输入内容
  283. !#:n # 本条命令之前的第n个单词, 快速备份cp /etc/passwd !#:1.bak
  284. ##############################################################################
  285. # 函数
  286. ##############################################################################
  287. # 定义一个新函数
  288. function myfunc() {
  289. # $1 代表第一个参数,$N 代表第 N 个参数
  290. # $# 代表参数个数
  291. # $0 代表被调用者自身的名字
  292. # $@ 代表所有参数,类型是个数组,想传递所有参数给其他命令用 cmd "$@"
  293. # $* 空格链接起来的所有参数,类型是字符串
  294. {shell commands ...}
  295. }
  296. myfunc # 调用函数 myfunc
  297. myfunc arg1 arg2 arg3 # 带参数的函数调用
  298. myfunc "$@" # 将所有参数传递给函数
  299. myfunc "${array[@]}" # 将一个数组当作多个参数传递给函数
  300. shift # 参数左移
  301. unset -f myfunc # 删除函数
  302. declare -f # 列出函数定义
  303. ##############################################################################
  304. # 条件判断(兼容 posix sh 的条件判断):man test
  305. ##############################################################################
  306. statement1 && statement2 # and 操作符
  307. statement1 || statement2 # or 操作符
  308. exp1 -a exp2 # exp1 和 exp2 同时为真时返回真(POSIX XSI扩展)
  309. exp1 -o exp2 # exp1 和 exp2 有一个为真就返回真(POSIX XSI扩展)
  310. ( expression ) # 如果 expression 为真时返回真,输入注意括号前反斜杆
  311. ! expression # 如果 expression 为假那返回真
  312. str1 = str2 # 判断字符串相等,如 [ "$x" = "$y" ] && echo yes
  313. str1 != str2 # 判断字符串不等,如 [ "$x" != "$y" ] && echo yes
  314. str1 < str2 # 字符串小于,如 [ "$x" \< "$y" ] && echo yes
  315. str2 > str2 # 字符串大于,注意 < 或 > 是字面量,输入时要加反斜杆
  316. -n str1 # 判断字符串不为空(长度大于零)
  317. -z str1 # 判断字符串为空(长度等于零)
  318. -a file # 判断文件存在,如 [ -a /tmp/abc ] && echo "exists"
  319. -d file # 判断文件存在,且该文件是一个目录
  320. -e file # 判断文件存在,和 -a 等价
  321. -f file # 判断文件存在,且该文件是一个普通文件(非目录等)
  322. -r file # 判断文件存在,且可读
  323. -s file # 判断文件存在,且尺寸大于0
  324. -w file # 判断文件存在,且可写
  325. -x file # 判断文件存在,且执行
  326. -N file # 文件上次修改过后还没有读取过
  327. -O file # 文件存在且属于当前用户
  328. -G file # 文件存在且匹配你的用户组
  329. file1 -nt file2 # 文件1 比 文件2 新
  330. file1 -ot file2 # 文件1 比 文件2 旧
  331. num1 -eq num2 # 数字判断:num1 == num2
  332. num1 -ne num2 # 数字判断:num1 != num2
  333. num1 -lt num2 # 数字判断:num1 < num2
  334. num1 -le num2 # 数字判断:num1 <= num2
  335. num1 -gt num2 # 数字判断:num1 > num2
  336. num1 -ge num2 # 数字判断:num1 >= num2
  337. ##############################################################################
  338. # 分支控制:if 和经典 test,兼容 posix sh 的条件判断语句
  339. ##############################################################################
  340. test {expression} # 判断条件为真的话 test 程序返回0 否则非零
  341. [ expression ] # 判断条件为真的话返回0 否则非零
  342. test "abc" = "def" # 查看返回值 echo $? 显示 1,因为条件为假
  343. test "abc" != "def" # 查看返回值 echo $? 显示 0,因为条件为真
  344. test -a /tmp; echo $? # 调用 test 判断 /tmp 是否存在,并打印 test 的返回值
  345. [ -a /tmp ]; echo $? # 和上面完全等价,/tmp 肯定是存在的,所以输出是 0
  346. test cond && cmd1 # 判断条件为真时执行 cmd1
  347. [ cond ] && cmd1 # 和上面完全等价
  348. [ cond ] && cmd1 || cmd2 # 条件为真执行 cmd1 否则执行 cmd2
  349. # 判断 /etc/passwd 文件是否存在
  350. # 经典的 if 语句就是判断后面的命令返回值为0的话,认为条件为真,否则为假
  351. if test -e /etc/passwd; then
  352. echo "alright it exists ... "
  353. else
  354. echo "it doesn't exist ... "
  355. fi
  356. # 和上面完全等价,[ 是个和 test 一样的可执行程序,但最后一个参数必须为 ]
  357. # 这个名字为 "[" 的可执行程序一般就在 /bin 或 /usr/bin 下面,比 test 优雅些
  358. if [ -e /etc/passwd ]; then
  359. echo "alright it exists ... "
  360. else
  361. echo "it doesn't exist ... "
  362. fi
  363. # 和上面两个完全等价,其实到 bash 时代 [ 已经是内部命令了,用 enable 可以看到
  364. [ -e /etc/passwd ] && echo "alright it exists" || echo "it doesn't exist"
  365. # 判断变量的值
  366. if [ "$varname" = "foo" ]; then
  367. echo "this is foo"
  368. elif [ "$varname" = "bar" ]; then
  369. echo "this is bar"
  370. else
  371. echo "neither"
  372. fi
  373. # 复杂条件判断,注意 || 和 && 是完全兼容 POSIX 的推荐写法
  374. if [ $x -gt 10 ] && [ $x -lt 20 ]; then
  375. echo "yes, between 10 and 20"
  376. fi
  377. # 可以用 && 命令连接符来做和上面完全等价的事情
  378. [ $x -gt 10 ] && [ $x -lt 20 ] && echo "yes, between 10 and 20"
  379. # 小括号和 -a -o 是 POSIX XSI 扩展写法,小括号是字面量,输入时前面要加反斜杆
  380. if [ \( $x -gt 10 \) -a \( $x -lt 20 \) ]; then
  381. echo "yes, between 10 and 20"
  382. fi
  383. # 同样可以用 && 命令连接符来做和上面完全等价的事情
  384. [ \( $x -gt 10 \) -a \( $x -lt 20 \) ] && echo "yes, between 10 and 20"
  385. # 判断程序存在的话就执行
  386. [ -x /bin/ls ] && /bin/ls -l
  387. # 如果不考虑兼容 posix sh 和 dash 这些的话,可用 bash 独有的 ((..)) 和 [[..]]:
  388. https://www.ibm.com/developerworks/library/l-bash-test/index.html
  389. ##############################################################################
  390. # 流程控制:while / for / case / until
  391. ##############################################################################
  392. # while 循环
  393. while condition; do
  394. statements
  395. done
  396. i=1
  397. while [ $i -le 10 ]; do
  398. echo $i;
  399. i=$(expr $i + 1)
  400. done
  401. # for 循环:上面的 while 语句等价
  402. for i in {1..10}; do
  403. echo $i
  404. done
  405. for name [in list]; do
  406. statements
  407. done
  408. # for 列举某目录下面的所有文件
  409. for f in /home/*; do
  410. echo $f
  411. done
  412. # bash 独有的 (( .. )) 语句,更接近 C 语言,但是不兼容 posix sh
  413. for (( initialisation ; ending condition ; update )); do
  414. statements
  415. done
  416. # 和上面的写法等价
  417. for ((i = 0; i < 10; i++)); do echo $i; done
  418. # case 判断
  419. case expression in
  420. pattern1a | pattern1b | ... )
  421. statements ;;
  422. pattern2 )
  423. statements ;;
  424. * )
  425. otherwise ;;
  426. esac
  427. # until 语句
  428. until condition; do
  429. statements
  430. done
  431. # select 语句
  432. select name [in list]; do
  433. statements that can use $name
  434. done
  435. ##############################################################################
  436. # 命令处理
  437. ##############################################################################
  438. command ls # 忽略 alias 直接执行程序或者内建命令 ls
  439. builtin cd # 忽略 alias 直接运行内建的 cd 命令
  440. enable # 列出所有 bash 内置命令,或禁止某命令
  441. help {builtin_command} # 查看内置命令的帮助(仅限 bash 内置命令)
  442. eval $script # 对 script 变量中的字符串求值(执行)
  443. ##############################################################################
  444. # 输出/输入 重定向
  445. ##############################################################################
  446. cmd1 | cmd2 # 管道,cmd1 的标准输出接到 cmd2 的标准输入
  447. < file # 将文件内容重定向为命令的标准输入
  448. > file # 将命令的标准输出重定向到文件,会覆盖文件
  449. >> file # 将命令的标准输出重定向到文件,追加不覆盖
  450. >| file # 强制输出到文件,即便设置过:set -o noclobber
  451. n>| file # 强制将文件描述符 n的输出重定向到文件
  452. <> file # 同时使用该文件作为标准输入和标准输出
  453. n<> file # 同时使用文件作为文件描述符 n 的输出和输入
  454. n> file # 重定向文件描述符 n 的输出到文件
  455. n< file # 重定向文件描述符 n 的输入为文件内容
  456. n>& # 将标准输出 dup/合并 到文件描述符 n
  457. n<& # 将标准输入 dump/合并 定向为描述符 n
  458. n>&m # 文件描述符 n 被作为描述符 m 的副本,输出用
  459. n<&m # 文件描述符 n 被作为描述符 m 的副本,输入用
  460. &>file # 将标准输出和标准错误重定向到文件
  461. <&- # 关闭标准输入
  462. >&- # 关闭标准输出
  463. n>&- # 关闭作为输出的文件描述符 n
  464. n<&- # 关闭作为输入的文件描述符 n
  465. diff <(cmd1) <(cmd2) # 比较两个命令的输出
  466. ##############################################################################
  467. # 文本处理 - cut
  468. ##############################################################################
  469. cut -c 1-16 # 截取每行头16个字符
  470. cut -c 1-16 file # 截取指定文件中每行头 16个字符
  471. cut -c3- # 截取每行从第三个字符开始到行末的内容
  472. cut -d':' -f5 # 截取用冒号分隔的第五列内容
  473. cut -d';' -f2,10 # 截取用分号分隔的第二和第十列内容
  474. cut -d' ' -f3-7 # 截取空格分隔的三到七列
  475. echo "hello" | cut -c1-3 # 显示 hel
  476. echo "hello sir" | cut -d' ' -f2 # 显示 sir
  477. ps | tr -s " " | cut -d " " -f 2,3,4 # cut 搭配 tr 压缩字符
  478. ##############################################################################
  479. # 文本处理 - awk / sed
  480. ##############################################################################
  481. awk '{print $5}' file # 打印文件中以空格分隔的第五列
  482. awk -F ',' '{print $5}' file # 打印文件中以逗号分隔的第五列
  483. awk '/str/ {print $2}' file # 打印文件中包含 str 的所有行的第二列
  484. awk -F ',' '{print $NF}' file # 打印逗号分隔的文件中的每行最后一列
  485. awk '{s+=$1} END {print s}' file # 计算所有第一列的合
  486. awk 'NR%3==1' file # 从第一行开始,每隔三行打印一行
  487. sed 's/find/replace/' file # 替换文件中首次出现的字符串并输出结果
  488. sed '10s/find/replace/' file # 替换文件第 10 行内容
  489. sed '10,20s/find/replace/' file # 替换文件中 10-20 行内容
  490. sed -r 's/regex/replace/g' file # 替换文件中所有出现的字符串
  491. sed -i 's/find/replace/g' file # 替换文件中所有出现的字符并且覆盖文件
  492. sed -i '/find/i\newline' file # 在文件的匹配文本前插入行
  493. sed -i '/find/a\newline' file # 在文件的匹配文本后插入行
  494. sed '/line/s/find/replace/' file # 先搜索行特征再执行替换
  495. sed -e 's/f/r/' -e 's/f/r' file # 执行多次替换
  496. sed 's#find#replace#' file # 使用 # 替换 / 来避免 pattern 中有斜杆
  497. sed -i -r 's/^\s+//g' file # 删除文件每行头部空格
  498. sed '/^$/d' file # 删除文件空行并打印
  499. sed -i 's/\s\+$//' file # 删除文件每行末尾多余空格
  500. sed -n '2p' file # 打印文件第二行
  501. sed -n '2,5p' file # 打印文件第二到第五行
  502. ##############################################################################
  503. # 排序 - sort
  504. ##############################################################################
  505. sort file # 排序文件
  506. sort -r file # 反向排序(降序)
  507. sort -n file # 使用数字而不是字符串进行比较
  508. sort -t: -k 3n /etc/passwd # 按 passwd 文件的第三列进行排序
  509. sort -u file # 去重排序
  510. sort -h file # 支持 K/M/G 等量级符号,可与 du 结合使用
  511. ##############################################################################
  512. # 快速跳转 - https://github.com/rupa/z
  513. ##############################################################################
  514. source /path/to/z.sh # .bashrc 中初始化 z.sh
  515. z # 列出所有历史路径以及他们的权重
  516. z foo # 跳到历史路径中匹配 foo 的权重最大的目录
  517. z foo bar # 跳到历史路径中匹配 foo 和 bar 权重最大的目录
  518. z -l foo # 列出所有历史路径中匹配 foo 的目录及权重
  519. z -r foo # 按照最高访问次数优先进行匹配跳转
  520. z -t foo # 按照最近访问优先进行匹配跳转
  521. ##############################################################################
  522. # 键盘绑定
  523. ##############################################################################
  524. bind '"\eh":"\C-b"' # 绑定 ALT+h 为光标左移,同 CTRL+b / <Left>
  525. bind '"\el":"\C-f"' # 绑定 ALT+l 为光标右移,同 CTRL+f / <Right>
  526. bind '"\ej":"\C-n"' # 绑定 ALT+j 为下条历史,同 CTRL+n / <Down>
  527. bind '"\ek":"\C-p"' # 绑定 ALT+k 为上条历史,同 CTRL+p / <Up>
  528. bind '"\eH":"\eb"' # 绑定 ALT+H 为光标左移一个单词,同 ALT-b
  529. bind '"\eL":"\ef"' # 绑定 ALT+L 为光标右移一个单词,同 ALT-f
  530. bind '"\eJ":"\C-a"' # 绑定 ALT+J 为移动到行首,同 CTRL+a / <Home>
  531. bind '"\eK":"\C-e"' # 绑定 ALT+K 为移动到行末,同 CTRL+e / <End>
  532. bind '"\e;":"ls -l\n"' # 绑定 ALT+; 为执行 ls -l 命令
  533. ##############################################################################
  534. # 网络管理:ip / ifconfig / nmap ...
  535. ##############################################################################
  536. ip a # 显示所有网络地址,同 ip address
  537. ip a show eth1 # 显示网卡 IP 地址
  538. ip a add 172.16.1.23/24 dev eth1 # 添加网卡 IP 地址
  539. ip a del 172.16.1.23/24 dev eth1 # 删除网卡 IP 地址
  540. ip link show dev eth0 # 显示网卡设备属性
  541. ip link set eth1 up # 激活网卡
  542. ip link set eth1 down # 关闭网卡
  543. ip link set eth1 address {mac} # 修改 MAC 地址
  544. ip neighbour # 查看 ARP 缓存
  545. ip route # 查看路由表
  546. ip route add 10.1.0.0/24 via 10.0.0.253 dev eth0 # 添加静态路由
  547. ip route del 10.1.0.0/24 # 删除静态路由
  548. ifconfig # 显示所有网卡和接口信息
  549. ifconfig -a # 显示所有网卡(包括开机没启动的)信息
  550. ifconfig eth0 # 指定设备显示信息
  551. ifconfig eth0 up # 激活网卡
  552. ifconfig eth0 down # 关闭网卡
  553. ifconfig eth0 192.168.120.56 # 给网卡配置 IP 地址
  554. ifconfig eth0 10.0.0.8 netmask 255.255.255.0 up # 配置 IP 并启动
  555. ifconfig eth0 hw ether 00:aa:bb:cc:dd:ee # 修改 MAC 地址
  556. nmap 10.0.0.12 # 扫描主机 1-1000 端口
  557. nmap -p 1024-65535 10.0.0.12 # 扫描给定端口
  558. nmap 10.0.0.0/24 # 给定网段扫描局域网内所有主机
  559. nmap -O -sV 10.0.0.12 # 探测主机服务和操作系统版本
  560. ##############################################################################
  561. # 有趣的命令
  562. ##############################################################################
  563. man hier # 查看文件系统的结构和含义
  564. man test # 查看 posix sh 的条件判断帮助
  565. man ascii # 显示 ascii 表
  566. getconf LONG_BIT # 查看系统是 32 位还是 64 位
  567. bind -P # 列出所有 bash 的快捷键
  568. mount | column -t # 漂亮的列出当前加载的文件系统
  569. curl ip.cn # 取得外网 ip 地址和服务商信息
  570. disown -a && exit # 关闭所有后台任务并退出
  571. cat /etc/issue # 查看 Linux 发行版信息
  572. lsof -i port:80 # 哪个程序在使用 80 端口?
  573. showkey -a # 取得按键的 ASCII 码
  574. svn diff | view - # 使用 Vim 来显示带色彩的 diff 输出
  575. mv filename.{old,new} # 快速文件改名
  576. time read # 使用 CTRL-D 停止,最简单的计时功能
  577. cp file.txt{,.bak} # 快速备份文件
  578. sudo touch /forcefsck # 强制在下次重启时扫描磁盘
  579. find ~ -mmin 60 -type f # 查找 $HOME 目录中,60 分钟内修改过的文件
  580. curl wttr.in/~beijing # 查看北京的天气预报
  581. echo ${SSH_CLIENT%% *} # 取得你是从什么 IP 链接到当前主机上的
  582. echo $[RANDOM%X+1] # 取得 1 到 X 之间的随机数
  583. bind -x '"\C-l":ls -l' # 设置 CTRL+l 为执行 ls -l 命令
  584. find / -type f -size +5M # 查找大于 5M 的文件
  585. chmod --reference f1 f2 # 将 f2 的权限设置成 f1 一模一样的
  586. curl -L cheat.sh # 速查表大全
  587. ##############################################################################
  588. # 常用技巧
  589. ##############################################################################
  590. # 列出最常使用的命令
  591. history | awk '{a[$2]++}END{for(i in a){print a[i] " " i}}' | sort -rn | head
  592. # 列出所有网络状态:ESTABLISHED / TIME_WAIT / FIN_WAIT1 / FIN_WAIT2
  593. netstat -n | awk '/^tcp/ {++tt[$NF]} END {for (a in tt) print a, tt[a]}'
  594. # 通过 SSH 来 mount 文件系统
  595. sshfs name@server:/path/to/folder /path/to/mount/point
  596. # 显示前十个运行的进程并按内存使用量排序
  597. ps aux | sort -nk +4 | tail
  598. # 在右上角显示时钟
  599. while sleep 1;do tput sc;tput cup 0 $(($(tput cols)-29));date;tput rc;done&
  600. # 从网络上的压缩文件中解出一个文件来,并避免保存中间文件
  601. wget -qO - "http://www.tarball.com/tarball.gz" | tar zxvf -
  602. # 性能测试:测试处理器性能
  603. python -c "import test.pystone;print(test.pystone.pystones())"
  604. # 性能测试:测试内存带宽
  605. dd if=/dev/zero of=/dev/null bs=1M count=32768
  606. # Linux 下挂载一个 iso 文件
  607. mount /path/to/file.iso /mnt/cdrom -oloop
  608. # 通过主机 A 直接 ssh 到主机 B
  609. ssh -t hostA ssh hostB
  610. # 下载一个网站的所有图片
  611. wget -r -l1 --no-parent -nH -nd -P/tmp -A".gif,.jpg" http://example.com/images
  612. # 快速创建项目目录
  613. mkdir -p work/{project1,project2}/{src,bin,bak}
  614. # 按日期范围查找文件
  615. find . -type f -newermt "2010-01-01" ! -newermt "2010-06-01"
  616. # 显示当前正在使用网络的进程
  617. lsof -P -i -n | cut -f 1 -d " "| uniq | tail -n +2
  618. # Vim 中保存一个没有权限的文件
  619. :w !sudo tee > /dev/null %
  620. # 在 .bashrc / .bash_profile 中加载另外一个文件(比如你保存在 github 上的配置)
  621. source ~/github/profiles/my_bash_init.sh
  622. # 反向代理:将外网主机(202.115.8.1)端口(8443)转发到内网主机 192.168.1.2:443
  623. ssh -CqTnN -R 0.0.0.0:8443:192.168.1.2:443 user@202.115.8.1
  624. # 正向代理:将本地主机的 8443 端口,通过 192.168.1.3 转发到 192.168.1.2:443
  625. ssh -CqTnN -L 0.0.0.0:8443:192.168.1.2:443 user@192.168.1.3
  626. # socks5 代理:把本地 1080 端口的 socks5 的代理请求通过远程主机转发出去
  627. ssh -CqTnN -D localhost:1080 user@202.115.8.1
  628. # 终端下正确设置 ALT 键和 BackSpace 键
  629. http://www.skywind.me/blog/archives/2021
  630. ##############################################################################
  631. # 有用的函数
  632. ##############################################################################
  633. # 自动解压:判断文件后缀名并调用相应解压命令
  634. function q-extract() {
  635. if [ -f $1 ] ; then
  636. case $1 in
  637. *.tar.bz2) tar -xvjf $1 ;;
  638. *.tar.gz) tar -xvzf $1 ;;
  639. *.tar.xz) tar -xvJf $1 ;;
  640. *.bz2) bunzip2 $1 ;;
  641. *.rar) rar x $1 ;;
  642. *.gz) gunzip $1 ;;
  643. *.tar) tar -xvf $1 ;;
  644. *.tbz2) tar -xvjf $1 ;;
  645. *.tgz) tar -xvzf $1 ;;
  646. *.zip) unzip $1 ;;
  647. *.Z) uncompress $1 ;;
  648. *.7z) 7z x $1 ;;
  649. *) echo "don't know how to extract '$1'..." ;;
  650. esac
  651. else
  652. echo "'$1' is not a valid file!"
  653. fi
  654. }
  655. # 自动压缩:判断后缀名并调用相应压缩程序
  656. function q-compress() {
  657. if [ -n "$1" ] ; then
  658. FILE=$1
  659. case $FILE in
  660. *.tar) shift && tar -cf $FILE $* ;;
  661. *.tar.bz2) shift && tar -cjf $FILE $* ;;
  662. *.tar.xz) shift && tar -cJf $FILE $* ;;
  663. *.tar.gz) shift && tar -czf $FILE $* ;;
  664. *.tgz) shift && tar -czf $FILE $* ;;
  665. *.zip) shift && zip $FILE $* ;;
  666. *.rar) shift && rar $FILE $* ;;
  667. esac
  668. else
  669. echo "usage: q-compress <foo.tar.gz> ./foo ./bar"
  670. fi
  671. }
  672. # 漂亮的带语法高亮的 color cat ,需要先 pip install pygments
  673. function ccat() {
  674. local style="monokai"
  675. if [ $# -eq 0 ]; then
  676. pygmentize -P style=$style -P tabsize=4 -f terminal256 -g
  677. else
  678. for NAME in $@; do
  679. pygmentize -P style=$style -P tabsize=4 -f terminal256 -g "$NAME"
  680. done
  681. fi
  682. }
  683. ##############################################################################
  684. # 好玩的配置
  685. ##############################################################################
  686. # 放到你的 ~/.bashrc 配置文件中,给 man 增加漂亮的色彩高亮
  687. export LESS_TERMCAP_mb=$'\E[1m\E[32m'
  688. export LESS_TERMCAP_mh=$'\E[2m'
  689. export LESS_TERMCAP_mr=$'\E[7m'
  690. export LESS_TERMCAP_md=$'\E[1m\E[36m'
  691. export LESS_TERMCAP_ZW=""
  692. export LESS_TERMCAP_us=$'\E[4m\E[1m\E[37m'
  693. export LESS_TERMCAP_me=$'\E(B\E[m'
  694. export LESS_TERMCAP_ue=$'\E[24m\E(B\E[m'
  695. export LESS_TERMCAP_ZO=""
  696. export LESS_TERMCAP_ZN=""
  697. export LESS_TERMCAP_se=$'\E[27m\E(B\E[m'
  698. export LESS_TERMCAP_ZV=""
  699. export LESS_TERMCAP_so=$'\E[1m\E[33m\E[44m'
  700. # ALT+hjkl/HJKL 快速移动光标,将下面内容添加到 ~/.inputrc 中可作用所有工具,
  701. # 包括 bash/zsh/python/lua 等使用 readline 的工具,帮助见:info rluserman
  702. "\eh": backward-char
  703. "\el": forward-char
  704. "\ej": next-history
  705. "\ek": previous-history
  706. "\eH": backward-word
  707. "\eL": forward-word
  708. "\eJ": beginning-of-line
  709. "\eK": end-of-line
  710. ##############################################################################
  711. # References
  712. ##############################################################################
  713. https://github.com/Idnan/bash-guide
  714. http://www.linuxstall.com/linux-command-line-tips-that-every-linux-user-should-know/
  715. https://ss64.com/bash/syntax-keyboard.html
  716. http://wiki.bash-hackers.org/commands/classictest
  717. https://www.ibm.com/developerworks/library/l-bash-test/index.html
  718. https://www.cyberciti.biz/faq/bash-loop-over-file/
  719. https://linuxconfig.org/bash-scripting-tutorial
  720. https://github.com/LeCoupa/awesome-cheatsheets/blob/master/languages/bash.sh
  721. https://devhints.io/bash
  722. https://github.com/jlevy/the-art-of-command-line
  723. https://yq.aliyun.com/articles/68541
  724. https://tiswww.case.edu/php/chet/bash/article.pdf
  725. # vim: set ts=4 sw=4 tw=0 et :