linux shell 编程基础知识
source link: https://xujinzh.github.io/2022/04/18/linux-shell-programming-basics/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
linux shell 编程基础知识
shell 是一个用 C 编写的程序,是用户与系统内核之间的桥梁。其提供了一个界面,用户通过该界面访问操作系统的内核服务。Ken Thompson 的 sh 是第一种 Unix Shell,Windows Explorer 是一个典型的图形界面 Shell。其实,shell 也是一种解释性的程序设计语言,用户通过编写 shell 脚本在 Linux 上进行自动运维等。常见的 Linux shell 种类很多,如 Bourne Shell(/usr/bin/sh或/bin/sh)、Bourne Again Shell(/bin/bash)、C Shell(/usr/bin/csh)、K Shell(/usr/bin/ksh)、Shell for Root(/sbin/sh)等,国内常用的是 /bin/bash,也是大多数 Linux 系统默认的 shell。在一般情况下,人们并不区分 Bourne Shell 和 Bourne Again Shell,所以,像 #!/bin/sh,它同样也可以改为 #!/bin/bash.
shell 脚本一般需要
- 以 #!/bin/bash 开头,#! 告诉系统其后路径所指定的程序即是解释此脚本文件的 Shell 程序;
- 脚本命名常以 .sh 结尾;
- 脚本需要可执行权限.
# 利用 vim 创建脚本 |
shell 变量
shell 变量分为系统变量和用户自定义变量。
系统变量常见的有:$HOME,$PWD,$SHELL,$USER
等等,查看某个系统变量值可使用命令echo $HOME
完成,当想查看所有系统变量时可使用命令:set
完成。
用户自定义变量
变量名称一般习惯为大写,不过小写也能通过。建议大写,遵守规范。
变量名的命名须遵循如下规则:
- 命名只能使用英文字母,数字和下划线,首个字符不能以数字开头
- 中间不能有空格,可以使用下划线 _
- 不能使用标点符号
- 不能使用bash里的关键字(可用help命令查看保留关键字)
注意,变量赋值等号两端不要有空格。用 $
获取变量值。
自定义变量常使用如下方法:
# 变量=值 |
撤销变量,撤销后无法使用该变量:
# unset 变量 |
声明静态变量,这种变量不能被 unset
# readonly 变量 |
将命令返回值赋值给变量
A=`date` |
预定义变量
预定义变量指 shell 设计者预先定义好的变量,可以直接在 shell 脚本中使用
$$
(功能:当前进程的进程号 PID);$!
(功能:后台运行的最后一个进程的进程号 PID);$?
(功能:最后依次执行的命令的返回状态,如果为 0,表示正确执行;如果非 0(具体值有命令决定),表示执行错误);- 一些获取位置参数的变量,下面介绍。
# 创建脚本 |
设置环境变量
export 变量=值
(功能:将 shell 变量输出为环境变量,直接在命令行运行,则直接生效但退出当前 shell 时失效。可以写入到配置文件 ~/.bashrc 或 /etc/profile 中);source 配置文件
(功能:让配置文件立即生效);echo $变量
(功能:查看环境变量是否失效)。
shell 注释
单号注释,在当前行开头添加 #
# A=3 |
多行注释,方法如下:
:<<! |
把需要注释的内容放在 :<<!
和 !
之间,建议注释符分别占一行。
当我们执行一个 shell 脚本时,如果希望获取到命令行的参数信息,需要位置参数,如下
# 将位置参数 100 和 99 供 hello.sh 使用 |
脚本中如何使用位置参数:
$n
(功能:n 为自然数,$0
表示命令本身,如 ./hello.sh,$1
表示第 1 个参数,如 100,依次类推,对于超过 9 个的位置参数,需增加大括号,如${10}
;$*
(功能:表示命令行中所有的参数,把所有参数看成一个整体);$@
(功能:表示命令行中所有的参数,不过不是看作一个整体,而是一个”数组”,可以按顺序读取);$#
(功能:表示命令行中所有参数的个数)。
# 编写脚本 |
像其他语言一样,shell 中也可以进行运算操作,方法如下:
$[运算式]
# 注意中括号和运算式之间可有一个空格,也可不要;$(( 运算式 ))
# 注意内层小括号和运算式之间可有一个空格,也可不要;expr 运算式
# expr 与运算式之间有一个空格,运算式中运算符与运算数之间有一个空格。常见运算有:expr \*, /, %
分别表示乘,除,取余;- 如果想将运算结果赋值给变量,需添加 ``,注意使用的是反引号 ` 而不是单引号 ‘,如 A=$[ 2 + 3 ] 或 A=`expr 2 + 3`
# 编写脚本 |
运算符包括算术运算符、关系运算符、布尔运算符、字符串运算符和文件测试运算符。
算术运算符
下表列出了常用的算术运算符,假定变量 a 为 10,变量 b 为 20:
运算符 | 说明 | 举例 |
---|---|---|
+ | 加法 | expr $a + $b 结果为 30。 |
- | 减法 | expr $a - $b 结果为 -10。 |
* | 乘法 | expr $a \* $b 结果为 200。 |
/ | 除法 | expr $b / $a 结果为 2。 |
% | 取余 | expr $b % $a 结果为 0。 |
= | 赋值 | a=$b 把变量 b 的值赋给 a。 |
== | 相等。用于比较两个数字,相同则返回 true。 | [ $a == $b ] 返回 false。 |
!= | 不相等。用于比较两个数字,不相同则返回 true。 | [ $a != $b ] 返回 true。 |
注意:条件表达式要放在方括号之间,并且要有空格,例如: [$a==$b]
是错误的,必须写成 [ $a == $b ]
。
关系运算符
关系运算符只支持数字,不支持字符串,除非字符串的值是数字。
下表列出了常用的关系运算符,假定变量 a 为 10,变量 b 为 20:
运算符 | 说明 | 举例 |
---|---|---|
-eq | 检测两个数是否相等,相等返回 true。 | [ $a -eq $b ] 返回 false。 |
-ne | 检测两个数是否不相等,不相等返回 true。 | [ $a -ne $b ] 返回 true。 |
-gt | 检测左边的数是否大于右边的,如果是,则返回 true。 | [ $a -gt $b ] 返回 false。 |
-lt | 检测左边的数是否小于右边的,如果是,则返回 true。 | [ $a -lt $b ] 返回 true。 |
-ge | 检测左边的数是否大于等于右边的,如果是,则返回 true。 | [ $a -ge $b ] 返回 false。 |
-le | 检测左边的数是否小于等于右边的,如果是,则返回 true。 | [ $a -le $b ] 返回 true。 |
布尔运算符
下表列出了常用的布尔运算符,假定变量 a 为 10,变量 b 为 20:
运算符 | 说明 | 举例 |
---|---|---|
! | 非运算,表达式为 true 则返回 false,否则返回 true。 | [ !false ] 返回 true。 |
-o | 或运算,有一个表达式为 true 则返回 true。 | [ $a -lt 20 -o $b -gt 100 ] 返回 true。 |
-a | 与运算,两个表达式都为 true 才返回 true。 | [ $a -lt 20 -a $b -gt 100 ] 返回 false。 |
逻辑运算符
以下介绍 Shell 的逻辑运算符,假定变量 a 为 10,变量 b 为 20:
运算符 | 说明 | 举例 |
---|---|---|
&& | 逻辑的 AND | [[ $a -lt 100 && $b -gt 100 ]] 返回 false |
|| | 逻辑的 OR | [[ $a -lt 100 || $b -gt 100 ]] 返回 true |
注意,运算式是有两个中括号嵌套包裹。
字符串运算符
下表列出了常用的字符串运算符,假定变量 a 为 “abc”,变量 b 为 “efg”:
运算符 | 说明 | 举例 |
---|---|---|
= | 检测两个字符串是否相等,相等返回 true。 | [ $a = $b ] 返回 false。 |
!= | 检测两个字符串是否不相等,不相等返回 true。 | [ $a != $b ] 返回 true。 |
-z | 检测字符串长度是否为0,为0返回 true。 | [ -z $a ] 返回 false。 |
-n | 检测字符串长度是否不为 0,不为 0 返回 true。 | [ -n "$a" ] 返回 true。 |
$ | 检测字符串是否为空,不为空返回 true。 | [ $a ] 返回 true。 |
文件测试运算符
文件测试运算符用于检测 Unix 文件的各种属性。
属性检测描述如下:
操作符 | 说明 | 举例 |
---|---|---|
-b file | 检测文件是否是块设备文件,如果是,则返回 true。 | [ -b $file ] 返回 false。 |
-c file | 检测文件是否是字符设备文件,如果是,则返回 true。 | [ -c $file ] 返回 false。 |
-d file | 检测文件是否是目录,如果是,则返回 true。 | [ -d $file ] 返回 false。 |
-f file | 检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。 | [ -f $file ] 返回 true。 |
-g file | 检测文件是否设置了 SGID 位,如果是,则返回 true。 | [ -g $file ] 返回 false。 |
-k file | 检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。 | [ -k $file ] 返回 false。 |
-p file | 检测文件是否是有名管道,如果是,则返回 true。 | [ -p $file ] 返回 false。 |
-u file | 检测文件是否设置了 SUID 位,如果是,则返回 true。 | [ -u $file ] 返回 false。 |
-r file | 检测文件是否可读,如果是,则返回 true。 | [ -r $file ] 返回 true。 |
-w file | 检测文件是否可写,如果是,则返回 true。 | [ -w $file ] 返回 true。 |
-x file | 检测文件是否可执行,如果是,则返回 true。 | [ -x $file ] 返回 true。 |
-s file | 检测文件是否为空(文件大小是否大于0),不为空返回 true。 | [ -s $file ] 返回 true。 |
-e file | 检测文件(包括目录)是否存在,如果是,则返回 true。 | [ -e $file ] 返回 true。 |
其他检查符:
- -S: 判断某文件是否 socket。
- -L: 检测文件是否存在并且是一个符号链接。
条件判断和流程控制
基本语法如下:
[ condition ] |
注意,condition 与中括号之间有一个空格;当 condition 为非空时,如 [ A ]
,返回 true;当为空 [ ]
时,返回 false.
应用实例,如当某个程序执行正确时,执行某子程序,判断为 [ $? ]
,0 为 true,大于 1 为 false.
if … else …
实例代码:
# 创建脚本 |
case $变量 in |
基本语法1
for 变量 in v1 v2 vn |
基本语法2
for (( 初始值; 循环控制条件; 变量变换)) |
实例代码:
# 编写脚本 |
while
while [ condition ] |
# 编写脚本 |
until 循环
until 循环执行一系列命令直至条件为 true 时停止。
until 循环与 while 循环在处理方式上刚好相反。
一般 while 循环优于 until 循环,但在某些时候—也只是极少数情况下,until 循环更加有用。
until 语法格式:
condition 一般为条件表达式,如果返回值为 false,则继续执行循环体内的语句,否则跳出循环。
until condition |
#!/bin/bash |
在循环过程中,有时候需要在未达到循环结束条件时强制跳出循环,Shell 使用两个命令来实现该功能:break 和 continue。
break命令
break命令允许跳出所有循环(终止执行后面的所有循环)。
下面的例子中,脚本进入死循环直至用户输入数字大于 5。要跳出这个循环,返回到shell提示符下,需要使用 break 命令。
#!/bin/bash |
continue
continue 命令与 break 命令类似,只有一点差别,它不会跳出所有循环,仅仅跳出当前循环。
对上面的例子进行修改:
#!/bin/bash |
运行代码发现,当输入大于 5 的数字时,该例中的循环不会结束,语句 echo “游戏结束” 永远不会被执行。
read 读取控制台输入
read (选项) (参数) |
# 编写脚本 |
shell 中有自带的系统函数,用户也可以自定义函数。
系统函数有很多,比如 basename, dirname 等
# basename [文件路径] [扩展名] |
# dirname [文件路径] |
自定义函数
[ function ] funcname [()] |
# 编写脚本 |
数组中可以存放多个值。Bash Shell 只支持一维数组(不支持多维数组),初始化时不需要定义数组大小(与 PHP 类似)。
与大部分编程语言类似,数组元素的下标由 0 开始。
Shell 数组用括号来表示,元素用”空格”符号分割开,语法格式如下:
array_name=(value1 value2 ... valuen) |
#!/bin/bash |
我们也可以使用下标来定义数组:
array_name[0]=value0 |
读取数组元素
读取数组元素值的一般格式是:
${array_name[index]} |
#!/bin/bash |
获取数组长度
#!/bin/bash |
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK