Shell编程指南

概述

作为一个开发人员,使用 Linux 实在是太频繁了,无论是观看别人程序的脚本,还是自己编写脚本,都离不开 Shell,所以这篇文章总结一下

什么是 shell?

Shell 是一个连接用户和操作系统内核(Kernel)的桥梁。Shell 是一个命令行解释器(Command-Line Interpreter)。它接收你输入的命令,将其翻译成内核能理解的指令,然后让内核去执行。执行完毕后,Shell 再把结果(通常是文本)返回并显示在你的屏幕上。

所以,你打开的那个黑乎乎的、可以输入命令的窗口(通常称为“终端”或“控制台”),里面运行的就是 Shell 程序。

常见的 Shell 类型

Shell 并非只有一种,它有许多不同的实现版本,各自具有不同的特性。最常见的有:

  • Bash (Bourne-Again Shell):这是最流行、最通用的 Shell,是绝大多数 Linux 发行版的默认 Shell,在 macOS 的旧版本中也是默认 Shell。它功能强大,易于学习。我们通常说的 “Shell 编程” 或 “Shell 脚本”,指的基本上就是 Bash。
  • Zsh (Z Shell):一个功能比 Bash 更强大的 Shell。它提供了更智能的自动补全、拼写纠错、更灵活的定制和丰富的主题(通过 Oh My Zsh 等框架)。现在是 macOS 的默认 Shell,也受到越来越多 Linux 用户的喜爱。
  • sh (Bourne Shell):一个非常古老的、经典的 Shell,是许多现代 Shell 的祖先。在很多系统中,/bin/sh 实际上是一个指向 Bash 或其他兼容 Shell 的链接。编写脚本时,为了保证最大的可移植性,有时会遵循 sh 的标准。

入门简介

解释器

Linux 中,解析脚本的是命令解释器,也就是终端解释器,如 Bash、Zsh。

在脚本中常见的头部声明如:

1
#!/bin/bash

或者

1
#!/bin/zsh

一般情况下 Linux 默认解释器是 bash

查看所有支持的 shell

1
cat /etc/shells

临时进入 解释器的方法为 exec 解释器

  • exec /bin/bash
  • exec /bin/zsh

查看当前解释器:echo $SHELL

脚本格式

脚本以 #!解释器 为开头

1
2
#!/bin/bash
# 脚本内容

按照习惯,bash 对应的脚本文件的后缀一般是 .sh 结尾,而 zsh 对应的脚本文件以 .zsh 结尾,当然,这不是必须的。

例如:在家目录新建目录 bin, 继续在 bin 目录新建一个文件 test1.sh

1
2
3
4
5
mkdir $HOME/bin

cd $HOME/bin

touch test.sh
1
vim test1.sh
1
2
#! /bin/sh
echo "我的解释器为 $SHELL"

脚本执行方式

在新建 test1.sh 之后,如何执行呢?

  • 方式 1
1
解释器 脚本路径

脚本的路径可使用相对路径也可以使用绝对路径

例如

1
2
3
4
# 切换到 bin 目录
cd $HOME/bin
# 相对路径
sh test1.sh
1
2
# 绝对路径,不用切换到对应目录
sh ~/bin/test1.sh

执行结果

1
我的解释器为 /bin/bash
  • 方式 2

对脚本增加可执行权限

1
chmod +x test1.sh

直接运行脚本

1
$HOme/bin/test1.sh

执行结果

1
我的解释器为 /bin/bash

变量

Shell 中可以设置变量,变量表示了一些值,通过特定的字符加特定的方式可以表达出来

如系统默认的变量:

  • SHELL:当前用户的解释器
  • USER:当前用户
  • HOME:当前用户的家目录

查看这些变量的值只需要 echo $变量名即可:

1
2
3
4
echo $SHELL

输出结果:
/bin/bash
1
2
3
4
echo $USER

输出结果:
ecs-user
1
2
3
4
echo $HOME

输出结果:
/home/ecs-user

系统变量

系统变量,顾名思义,就是系统自带的变量

除了已经介绍过的SHELL、USER、HOME等外,还有如:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
PATH:环境变量,包含了可执行文件的搜索路径。
BASH_VERSION:Bash shell的版本信息。
PWD:当前工作目录的绝对路径。
LANG:系统的语言和字符集设置。
TERM:终端类型。
LOGNAME:当前登录的用户名。
HISTSIZE:命令历史记录的数量。
LINES:终端的行数。
USER:非root用户的用户名。
UID:用户ID(root用户为0)。
GID:组ID(root用户为0)。

使用env命令查看当前系统定义的所有环境变量

使用set命令显示所有本地定义的 Shell 变量

自定义变量

除了系统自带的系统变量以外,用户还可以自定义属于自己的变量

基本语法:

  • 定义变量:变量名=变量值等号两边不能有空格
  • 撤销变量:unset 变量名
  • 静态变量:readonly 变量名,静态变量不可撤销
  • 全局变量:export 变量名

变量命名规则

  • 必须以字母(a-z、A-Z)或下划线(_)开头
  • 区分大小写,环境变量命名建议大写
  • 不能是内置命令或关键字
  • 长度不能超过 99 个字符
  • 不能包含空格或其他特殊字符

变量小贴士

  • 变量默认类型都是字符串类型,无法直接进行数值运算
  • 变量的值如果有空格,需要使用双引号或单引号括起来

特殊变量

除了系统变量,自定义变量,还有一些特殊的变量,它们经常在 shell 脚本中使用

$n

n 代表是数字,如 0、1、2、3,…,在大于 9 后,需要用 {} 包裹,如 ${10}

$0:表示当前脚本的名称或路径

如:

example.sh

1
2
#!/bin/bash
echo "this script name is $0"

执行脚本

1
sh example.sh

输出内容

1
this script name is example.sh

脚本 2

1
2
#!/bin/bash
echo "this script name is $0, parms is: $1 $2 $3 $4"

执行脚本

1
sh example2.sh i love shell

输出结果

1
this script name is example2.sh, parms is: i love shell

这里第 4 个参数,没有赋予,结果也没有显示

$#

$#:获取所有输入参数的个数

1
2
#!/bin/bash
echo "params count: $#"

运行

1
sh example3.sh this is a examle

运行结果

1
params count: 4

$*$@

  • $*:代表命令行中所有的参数,把所有的参数看成一个整体
  • $@:代表命令行中所有的参数,把每个参数区分对待

例:

example4.sh

1
2
3
4
5
#!/bin/bash
echo '----- $@ -----'
echo $@
echo '----- $* -----'
echo $*

运行

1
sh example4.sh i love shell

运行结果

1
2
3
4
----- $@ -----
i love shell
----- $* -----
i love shell

$?

$?:返回上一次执行结果的状态,如果为 0,表示正确执行,如果非 0,表示不正确执行

例如:

example5.sh

1
2
3
4
5
#!/bin/bash
echo '----- $? -----'
echo $?
num = 10
echo $?

运行

1
sh example5.sh

运行结果

1
2
3
4
----- $? -----
0
example5.sh: 4: num: not found
127

结果解释

  • 0:表示前一个命令 echo '----- $? -----' 运行成功了
  • 127:因为num = 10 变量赋值之间有空格,失败了,所以后面的 echo $?输出了一个非 0 数字

运算符

shell 中有运算表达式,可以进行运算

语法:

  • $((运算表达式))
  • $[ 运算表达式 ]:注意左右空格

例 1:

shell03_01.sh

1
2
#!/bin/bash
echo $((1+1))

运行

1
sh shell03_01.sh

运行结果

1
2

例 2:

shell03_02.sh

1
2
#!/bin/bash
echo $[ 1+1 ]

运行,注意是 bash

1
bash shell03_02.sh

运行结果

1
2

条件判断

shell 支持多种条件判断的方式

  • if…else
  • case..when
网站总访客数:Loading
网站总访问量:Loading
使用 Hugo 构建
主题 StackJimmy 设计
-->