Shell 编程基础知识总结
Shell 编程在我们的日常开发工作中非常实用,目前 Linux 系统下最流行的运维自动化语言就是 Shell 和 Python 了。 这篇文章我会简单总结一下 Shell 编程基础知识,带你入门
Shell 编程在我们的日常开发工作中非常实用,目前 Linux 系统下最流行的运维自动化语言就是 Shell 和 Python 了。 这篇文章我会简单总结一下 Shell 编程基础知识,带你入门 Shell 编程! 版本说明 本文示例适用于 bash 4.0+ 版本 。不同版本的 bash 在某些特性上可能有差异,特别是: 数组 :bash 2.0+ 支持,纯 POSIX sh(如 dash)不支持。 某些字符串操作 :如 在较旧版本可能不支持。 算术扩展 :bash 2.0+ 支持。 检查你的 bash 版本: 走进 Shell 编程的大门 为什么要学 Shell? 学一个东西,我们大部分情况都是往实用性方向着想。从工作角度来讲,学习 Shell 是为了提高我们自己工作效率,提高产出,让我们在更少的时间完成更多的事情。 很多人会说 Shell 编程属于运维方面的知识了,应该是运维人员来做,我们做后端开发的没必要学。我觉得这种说法大错特错,相比于专门做 Linux 运维的人员来说,我们对 Shell 编程掌握程度的要求要比他们低,但是 Shell 编程也是我们必须要掌握的! 目前 Linux 系统下最流行的运维自动化语言就是 Shell 和 Python 了。 两者之间,Shell 几乎是 IT 企业必须使用的运维自动化编程语言,特别是在运维工作中的服务监控、业务快速部署、服务启动停止、数据备份及处理、日志分析等环节里,Shell 是不可缺的。Python 更适合处理复杂的业务逻辑,以及开发复杂的运维软件工具,实现通过 web 访问等。Shell 是一个命令解释器,解释执行用户所输入的命令和程序。一输入命令,就立即回应的交互的对话方式。 另外,了解 Shell 编程也是大部分互联网公司招聘后端开发人员的要求。下图是我截取的一些知名互联网公司对于 Shell 编程的要求。 什么是 Shell? Shell 是 Linux/Unix 系统的命令解释器 ,它充当用户和操作系统内核之间的桥梁,负责接收用户输入的命令并调用相应的程序。 Shell 编程 是通过 Shell 解释器(如 bash)将命令、控制结构(if/for/while)、变量和函数组合成自动化脚本的过程。Shell 既是命令解释器,也是一门完整的编程语言(支持变量、数组、函数、流程控制、管道、重定向等)。 常见的 Shell 类型 : bash (Bourne Again Shell):Linux 系统默认 Shell,最常用。 sh (Bourne Shell):Unix 传统 Shell,POSIX 标准。 zsh :功能强大的交互式 Shell。 dash :轻量级 Shell,Ubuntu 的 /bin/sh 默认指向它。 csh/tcsh :C 风格的 Shell。 Shell 编程的 Hello World 学习任何一门编程语言第一件事就是输出 HelloWorld 了!下面我会从新建文件到 Shell 代码编写来说下 Shell 编程如何输出 Hello World。 (1)新建一个文件 helloworld.sh: ,扩展名为 sh(sh 代表 Shell)(扩展名并不影响脚本执行,见名知意就好,如果你用 php 写 Shell 脚本,扩展名就用 php 好了)。 (2)使脚本具有执行权限: (3)使用 vim 命令修改 helloworld.sh 文件: (vim 文件 进入文件 命令模式 按 i 进入编辑模式 编辑文件 按 Esc 进入底行模式 输入:wq/q!(输入 wq 代表写入内容并退出,即保存;输入 q! 代表强制退出不保存。)) helloworld.sh 内容如下: Shell 中 符号表示注释。 Shell 的第一行比较特殊,一般都会以 开始来指定使用的 Shell 类型。在 Linux 中,除了 bash Shell 以外,还有很多版本的 Shell,例如 zsh、dash 等等...不过 bash Shell 还是我们使用最多的。 (4)运行脚本: 。(注意,一定要写成 ,而不是 ,运行其它二进制的程序也一样,直接写 ,Linux 系统会去 PATH 里寻找有没有叫 helloworld.sh 的,而只有 /bin、/sbin、/usr/bin、/usr/sbin 等在 PATH 里,你的当前目录通常不在 PATH 里,所以写成 是会找不到命令的,要用 告诉系统说,就在当前目录找。) Shell 变量 Shell 编程中的变量介绍 Shell 编程中一般分为三种变量: 1. 自定义变量(局部变量) :默认仅在当前 Shell 进程内有效, 子进程无法访问 。若需传递给子进程,需使用 声明为环境变量。 2. 环境变量 :例如 、 等,可被子进程继承。使用 命令可以查看所有环境变量, 命令可以查看所有变量(包括环境变量和局部变量)。 3. Shell 特殊变量 :由 Shell 设置的特殊变量(如 、 、 等),用于保存进程状态、参数等信息。 常用的环境变量: PATH 决定了 Shell 将到哪些目录中寻找命令或程序。 HOME 当前用户主目录。 HISTSIZE 历史记录数。 LOGNAME 当前用户的登录名。 HOSTNAME 指主机的名称。 SHELL 当前用户 Shell 类型。 LANGUAGE 语言相关的环境变量,多语言可以修改此环境变量。 MAIL 当前用户的邮件存放目录。 PS1 基本提示符,对于 root 用户是 ,对于普通用户是 $。 使用 Linux 已定义的环境变量: 比如我们要看当前用户目录可以使用: 命令;如果我们要看当前用户 Shell 类型可以使用 命令。可以看出,使用方法非常简单。 使用自己定义的变量: Shell 编程中的变量名的命名的注意事项: 命名只能使用英文字母、数字和下划线,首个字符不能以数字开头,但是可以使用下划线(\ )开头。 中间不能有空格,可以使用下划线(\ )。 不能使用标点符号。 不能使用 bash 里的关键字(可用 help 命令查看保留关键字)。 Shell 字符串入门 字符串是 Shell 编程中最常用最有用的数据类型(除了数字和字符串,也没啥其它类型好用了),字符串可以用单引号,也可以用双引号。这点和 Java 中有所不同。 在单引号中,所有特殊字符(如 、反引号、 等)都失去特殊含义,被视为字面量。 在双引号中,以下字符保留特殊含义: :变量扩展(如 )和命令替换(如 或 ` cmd \ ` $() $() ! ${} ${ var} expr expr length ${ var} expr "$var" : '. ' \ unset array[1] ${array[1]} "${!array[@]}" "${array[@]}" expr $a + $b expr $a $b expr $a \ $b expr $b / $a expr $b % $a a=$b [ "$a" == "$b" ] [ "$a" != "$b" ] $((...)) expr ... $(...) [[ $a lt 100 && $b gt 100 ]] [[ $a lt 100 || $b gt 100 ]] && || [[ ]] && || command1 && command2 || command3 [ ! false ] [ "$a" lt 20 o "$b" gt 100 ] [ "$a" lt 20 a "$b" gt 100 ] [ "$a" = "$b" ] [ "$a" != "$b" ] [ z "$a" ] [ n "$a" ] [ "$a" ] file="/usr/learnshell/test.sh" if [ r $file ] w $file : true local read r r echo local $n n = 10 ${n} $10 $1 0 $0 $ $ $@ $ $@ "$@" !/bin/bash !/usr/bin/env bash !/bin/bash !/usr/bin/env bash [[ ]] [ ] $((...)) expr $(...) ${n} pipefail timeout xargs P & /tmp/test.log $$ flock SET key value NX PX timeout UNIQUE INDEX max time local ${ var} $((...)) [[ ]] [ ] [[ ]] command1 && command2 || command3 local $(...) read r command v timeout trap /dev/null 2 &1 set o pipefail trap $$ flock shellcheck sed awk grep` 等文本处理工具。 3. 学习正则表达式和文本处理技巧。 4. 了解性能优化和并发处理。 生产实践 : 1. 阅读 Google Shell Style Guide。 2. 研究开源项目的 Shell 脚本。 3. 在测试环境充分验证后再部署。 4. 建立完善的监控和告警机制。 参考资源 官方文档 :Bash Reference Manual(GNU) 代码检查 :ShellCheck Shell Script Analysis Tool 编码规范 :Google Shell Style Guide 常见陷阱 :Bash Pitfalls (<http://mywiki.wooledge.org/BashPitfalls )