shell编程(六) : [shell基础] 基本shell脚本

接上一篇文章Linux shell编程(五): Linux文件权限管理

三、Linux shell 脚本编程基础

了解了Linux系统和命令行的基础知识,是时候开始编程了。

3.1 基本shell脚本

shell脚本的关键在于输入多个命令并处理每个命令的结果,甚至需要将一个命令的结果传给另一个命令。如果要两个命令一起运行,可以把它们放在同一行中,彼此间用分号隔开,也就是前面讲过的命令列表,如下:

在这里插入图片描述

这就是一个shell脚本,但每次执行命令时都要重新输入这个语句,可以将它写到文本文件中,以后只要运行这个文件就行了,这就是shell脚本文件。

在创建shell脚本文件时,必须在文件的第一行指定要使用的shell版本,如下:

#!/bin/bash
whoami
date

可以仍然将 whoamidate ,放在一行并用分号隔开,也可以将他们独立成行,shell会按根据命令在文件中出现的顺序进行处理。

注:shell脚本的注释是以 # 开头的(指定shell版本以 #! 开头)

将上述shell脚本文件保存成名为shelltest的文件,并执行这个脚本文件,如下:

在这里插入图片描述

可以看到,显示找不到这个命令,前面讲过shell会通过 PATH 环境变量来查找命令,如果 PATH 环境变量里没有当前脚本文件所在路径,就会显示上述结果并尽可能给出可安装的推荐命令。要让shell可以找到脚本有多种方法:

  1. PATH 环境变量中添加脚本文件所在的绝对路径;
  2. PATH 环境变量中添加 ./ 路径;
  3. 执行脚本时,使用脚本文件的绝对或相对路径。

这里使用方法3,使用相对路径执行脚本文件:

在这里插入图片描述

看到没有权限,这是因为Linux新建的文件默认没有执行权限,按照前面所讲的,使用 chmod u+x shelltest 命令为脚本文件添加执行权限即可:

在这里插入图片描述

所以,在执行shell脚本时,要注意到不仅要让shell可以找到脚本文件,还要保证当前执行脚本的用户对shell脚本文件有执行权限。

为更好地区分,常将bash shell文本文件保存为 .sh 后缀的文件,如 shelltest.sh

3.1.1 显示信息

就像c语言的 print() 函数一样,shell也有自己的输出方式 – echo 命令。

把要显示的内容放在 echo 后面即可,如下:

#!/bin/bash
echo hello world!

默认情况下,不需要使用引号将要显示的文本字符串划定出来。

但如果输出内容中有 '" 等,则需要将输出内容用 ""'' 括起来,否则输出会出现问题。

另外,echo 命令输出后默认在行尾加换行符,如果不希望换行,可以使用 -n 选项,如下:

echo "hello"
echo " world!"
----------------------
hello
 world!
echo -n "hello"
echo " world!"
----------------------
hello world!

3.1.2 使用变量

既然是编程,就要有变量进行数据处理,前面讲过环境变量,可以理解为系统层面的全局变量,在脚本中可以访问这些值。

shell访问变量的语法为在变量名前加 $ 符号,如下:

echo $HOME
----------------------
/home/vistar

也可以自定义变量,和大多数程序语言一样,shell程序变量的赋值也使用 = ,但 = 两端不允许有空格,这个原因在前面介绍过(shell语句的命令与参数是用空格分割的,shell会将变量名误认为是一条命令,然而它只是一个变量)。

另外,定义shell变量时,不需要指定数据类型,因为shell脚本会自动决定变量值的数据类型。

shell变量常见的用途是存储命令的输出内容,以便于对命令输出做各种处理。

有两种方法可以将命令输出赋给变量,也叫作 命令替换

# 反引号字符: `` (Tab键上面那个键)
date1=`date`
echo date1: $date1

# $()
date2=$(date)
echo date2: $date2

在这里插入图片描述

date 是shell编程中很一个有用的命令,详解见 Linux date 命令详解

3.1.3 输入重定向和输出重定向

有时需要将结果保存到文件或从文件导入数据,shell提供了重定向操作。

  • 输入重定向: <<<
  • 输出重定向: >>>

输出重定向

即将原本输出到屏幕的内容重定向输出到文件里,如下:

在这里插入图片描述

如果重定向的文件已经存在,则重定向内容会覆盖原来文件的内容,如果想在原来文件内容后面追加重定向内容,可以使用符号 >> ,如下:

在这里插入图片描述

输入重定向

将文件的内容重定向到命令,如 Linux shell编程(四): Linux 用户和组管理 讲到的批量修改用户密码,就是输入重定向:

sudo chpasswd < passwd.txt

还有另外一种输入重定向的方法,称为内联输入重定向(inline input redirection)。这种方法无需使用文件进行重定向,它可以读取交互shell中输入的数据,重定向到命令,内联输入重定向使用符号 << ,如下:

在这里插入图片描述

其中,wc 是命令,它可以对数据中的文本进行计数,输出的三个值依次为:行数、次数、字节数。

<< 是内联重定向符号,end 是自定义的内联重定向结束标志,当读取到该标志时,内联重定向结束。

3.1.4 管道

前面介绍子shell时介绍过管道,它可以将一个命令的输出作为另一个命令的输入。如下:

在这里插入图片描述

不要以为由管道串起的两个命令会依次执行。Linux系统实际上会同时运行这两个命令,在系统内部将它们连接起来。在第一个命令产生输出的同时,输出会被立即送给第二个命令。数据传输不会用到任何中间文件或缓冲区。

3.1.5 数学运算

最开始的Bourne shell使用 expr 命令处理数学运算,但不是很好用,后来bash shell提供了更简单好用的方法,在将一个数学运算结果赋给某个变量时,用美元符和方括号 $[ operation ] 将数学表达式围起来,如下:

在这里插入图片描述

可以看到,c=8/6=1 ,这是因为bash shell数学运算符只支持整数运算,看似是一个不幸的消息,怎么办呢,有一些解决方案,其中最常见的一种是 bash计算器 ,叫作 bc

bc 允许在命令行中输入浮点表达式,然后解释并计算该表达式,最后返回结果。

bc 计算器能识别以下内容:

  • 数字(整数和浮点数)
  • 变量(简单变量和数组)
  • 注释(以#开始的行或/* */包含的内容)
  • 表达式
  • 编程语句(例如if-then语句)
  • 函数

可以在shell中运行 bc

在这里插入图片描述

输入数学计算式,回车即可输出结果,但 8/6 的结果仍然显示为 1 ,这是因为 bc 计算浮点运算,默认小数位数为0,可以通过內建变量 scale 设置小数位数,如下:

在这里插入图片描述

可以看到,结果按照设置的小数位数显示了,输入 quit 退出 bc

bc-q 选项可以不显示bash计算器冗长的欢迎信息,如下:

在这里插入图片描述

在脚本中使用 bc 需要借助前面介绍的 命令替换管道 ,格式如下:

variable=$(echo "options; expression" | bc)

其中,variable 是自定义的变量名,用以接收计算结果, options 是在 bc 的内置变量,多个变量用 ; 隔开,还有, expression 是计算表达式。

bc 有4个内置变量,

变量 描述
scale 指定精度,即小数点后的位数;默认为 0
ibase 指定输入的数字的进制,默认为十进制
obase 指定输出的数字的进制,默认为十进制
last/. 表示最近打印的数字

在这里插入图片描述

计算时也可以使用脚本文件中已定义的变量,如下:

在这里插入图片描述

对于比较复杂的计算式,可以使用前面介绍的内联输入重定向方法:

在这里插入图片描述

bc 中也可以给变量赋值,但在 bc 中创建的变量只在 bc 中有效,不能在shell脚本中使用。

3.1.6 退出脚本

shell中运行的每个命令都使用退出状态码告诉shell它已经运行完毕。退出状态码是一个0~255的整数值,在命令结束运行时由命令传给shell。可以捕获这个值并在脚本中使用。

Linux提供了一个专门的变量 $? 来保存上个已执行命令的退出状态码。一个成功结束的命令的退出状态码是 0 。如果一个命令结束时有错误,退出状态码就是一个正值。无效命令会返回一个退出状态码 127 。

一些退出状态码如下:

状态码 描述
0 命令成功结束
1 未知错误(参数无效等)
2 不适合的shell命令
126 命令不可执行(无权限)
127 没找到命令
128 无效的退出参数
128+x 与Linux信号x相关的严重错误
130 通过Ctrl+C终止的命令
255 正常范围之外的退出状态码

默认情况下,shell脚本会以脚本中的最后一个命令的退出状态码退出,也可以使用 exit 命令为自己的脚本指定退出状态码。如下:

在这里插入图片描述

也可以使用变量作为 exit 命令的参数,

在这里插入图片描述

但自定义状态码也必须在0-255范围内,否则状态码会以原状态码对256取模作为结果,如下:

在这里插入图片描述

自定义的状态码是 300,结果输出的是 44300%256 的结果是 44

下一篇:Linux shell编程(七): 使用结构化命令

猜你喜欢

转载自blog.csdn.net/maizousidemao/article/details/122910989