Linux shell编程学习 -- 进阶篇 - shell基础

学习目标:从认识Linux命令行基础开始,一直到写出自己的shell脚本

初识脚本

shell多命令

    shell脚本的关键在于输入多个命令并处理每个每个命令的结果,甚至需要讲一个命令的结果传给另外一个命令。shell可以将多个命令串起来一次执行完成。将命令放在同一行,并用分号隔开。(命令个数不超过最大命令行字符数255)
多命令执行

创建shell脚本
  • 使用文本编辑器创建shell脚本,通常为xxx.sh。
  • 在创建shell脚本文件时,必须在文件的第一行指定要使用的shell,其格式为
 #! /bin/bash
  • 在通常的shell脚本中,使用(#)作为注释符号
  • 可以根据需要,使用分号将两个命令放在一行上,但在shell脚本中,可以使用独立的行书写命令,shell会按根据命令在文件中出现的顺序进行处理。

    若编写好的脚本需要让bash shell环境识别,需要将脚本所处的目录添加到PATH环境变量中,或者在提示符中使用绝对或相对文件路径来引用shell脚本文件。
    每一个新的shell脚本在编写好后待执行前都需要更改权限。

显示消息

    大多数shell命令都会产生自己的输出,这些输出会显示在脚本所运行的控制台显示器上。如果想要添加自己的文本消息来告诉脚本用户现在的情况,需要使用echo命令实现。默认情况下,不需要使用引号将要显示的文本字符串划定出来。

  • echo命令可用单引号或双引号来划定文本字符串。如果在字符串中使用它们,需要在文本中使用其中一种引号,而使用另外一种来划定
  • echo -n 参数实现输出不换行
使用变量

    通常需要在shell命令中使用其他数据来处理信息,这可以通过变量来实现。变量允许临时性地将信息存储在shell脚本中,以便和脚本中的其他命令一起使用。

环境变量

    shell维护着一组环境变量,用来记录特定的系统信息。可以使用set命令来显示一份完整的当前环境变量列表。在脚本中可以使用($)对这些环境变量进行引用

echo $HOME

    若在脚本中不需要使用$的引用而是显示美元符,则必须在前面放置一个反斜线(\)

还可以通过${variable}形式引用变量。变量名两侧额外的花括号通常用来帮助是被美元符后面的变量名

用户变量

    shell脚本中的用户变量可以是任何由数字、字母或下划线组成的文本字符串,长度不超过20个。

  • 用户变量区分大小写
  • 使用等号将值赋给用户变量,在变量、等号和值之间不能出现空格
  • shell脚本会自动决定变量值的数据类型
  • 在脚本的整个生命周期里,shell脚本中定义的变量会一直保持它们的值,但在shell脚本结束时会被删除掉
  • 变量每次被引用时,都会输出当前赋给它的值
  • 引用一个变量值时需要使用美元符号,而引用变量来对其进行赋值时则不要使用美元符
命令替换

    shell脚本中最有用的特性之一就是可以从命令输出中提取信息,并将其赋给变量,有两种方法可可以将命令输出赋给变量:

  • 反引号字符(`)
  • $() 格式
  • 赋值等号和命令替换字符之间没有空格
  • 提取日期信息来生成日志文件名通常使用date命令加上格式实现
    date格式输出
  • 使用命令替换会创建一个子shell来运行对应的命令。子shell是由运行该脚本的shell所创建出来的一个独立shell,因此该子shell所执行命令是无法使用脚本中所创建的变量的
重定向输入和输出

    bash shell提供了几个操作符,可以将命令的输出重定向到另一个位置(比如文件)。重定向可以用于输入也可以用于输出

  • (>)大于号用于将命令的输出发送到一个文件中。如果文件已存在,会进行覆盖操作
  • (>>) 如果不想覆盖文件原有内容,使用双大于号可以将命令的输出追加到已有文件中
  • (<)小于号用于实现输入重定向,即将文件的内容重定向到命令
  • (<<)双小于号,实现内联输入重定向,另外必须使用一个文本标记来划分输入数据的开头和结尾

通过将文本文件重定向到wc命令,可以得到文件中的行、词和字节的计数

管道

    将命令输出重定向到另一个的命令的过程叫作管道连接

  • 使用(|)实现,使用管道时符号两侧的命令会同时运行,在系统内部连接起来
  • 在第一个命令产生 输出的同时,输出会被立即送给第二个命令。数据传输不会用到任何中间文件或缓冲区
  • 在一条命令中使用任意多条管道。可以持续地将命令的输出通过管道传给其他命令来细化操作
执行数学操作

     在shell脚本中,数学处理过程相对会比较麻烦。在shell脚本中有两种途径来进行数学运算

expr命令

    expr命令允许在命令行上处理数学表达式,它能识别少数的数学和字符串操作符。值得注意的是,需要将一个数据算式的结果赋给一个变量,需要使用命令替换来获取expr命令的输出。
操作符

方括号

    bash shell提供了一种更简单的方法来执行数学表达式。在bash中,将一个数学运算结果赋给某个变量时,可以用美元符和方括号($[ operation ])将数学表达式围起来,这种方式更方便且更适用于shell脚本。但是bash shell中数据运算符只支持整数运算。

浮点解决方案

    内建bash计算器,叫作bc,它是一种编程语言,它允许在命令行中输入浮点表达式,然后解释并计算该表达式,最后返回结果。bash计算器能够识别:

  • 数字(整数和浮点数)
  • 变量(简单变量和数组)
  • 注释(以#或C语言中/* */开始的行)
  • 表达式
  • 函数

    在脚本中使用bc,可以通过命令替换运行bc命令,并将输出赋能给一个变量。
在这里插入图片描述
    将选项和表达式放在脚本的不同行中可以让处理过程变得更清晰,提高易读性。EOF文本字符串标识了内联重定向数据的起止。当然,必须用命令替换符号表示出用来给变量赋值的命令。

退出脚本

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

  • $?变量用来保存上个已执行命令的退出状态码
  • 按照管理,一个成功结束的命令的退出状态码是0,如果一个命令结束时有错误,退出状态码就是一个正数值
    命令运行状态码
        exit命令
  • exit命令运行在脚本结束时指定一个退出状态码
  • 退出码最大只能是255,如果exit指定退出状态码大于该值,那么最终的结果是指定的数值除以256后得到的余数

结构化命令

if-then语句
格式:
if command
then
	commands
fi

    在其他的编程语言中,if语句之后的对象是一个等式,这个等式的求值结果为TRUE或FALSE。对于bash shell而言,if语句会运行if后面的那个命令,如果该命令的退出状态码是0(表示命令成功运行),then部分的命令就会被执行。如果该命令的退出状态码是其他值,then命令不会执行。bash shell会继续执行下一个命令。fi语句用来表示if-then语句到此结束。

if-then-else语句

    添加else的功能与其他语言中else作用类似。

格式:
if command
then
	commands
else
	commands
fi

    当if语句中的没给你了那个返回退出状态码0时,then部分中的命令会被执行,这跟普通的if-then语句一样。当if语句中的命令返回非零退出状态码时,bash shell会执行else部分中的命令。

嵌套if

    当需要检查脚本代码中的多种条件时就需要使用到嵌套的if-then语句。对于嵌套中else的部分,可以使用elif来表示。

格式:
if command1
then 
	commands
elif command2
then
	more commands
fi
test命令

    test命令提供了在if-then语句中测试不同条件的途径。如果test命令中列出的条件成立,test命令就会退出并返回退出状态码0。如果条件不成立或没有条件,test命令就会退出并返回非零的退出状态码。

格式:
test condition
//
if test condition
then 
	commands
fi
// 另一种条件测试方法
if [ condition ]
then
	commands
fi

    test命令可以判断三类条件:

  • 数值比较(bash shell只能处理整数)
    数值比较

  • 字符串比较
    字符串比较

  • 文件比较
    文件比较

复合条件测试

    if-then语句允许使用布尔逻辑来组合测试,逻辑与C语言中条件语句特性相同

格式:
[ condition1 ] && [ condition2 ]
[ condition1 ] || [ condition2 ]
if-then的高级特性

    bash shell提供了两项可在if-then语句中使用的高级特性

  • 用于数据表达式的双括号
    • 双括号提供了更多的数学符号,格式((expression))
      双括号命令符号
  • 用于高级字符串处理功能的双方括号
    • 双方括号命令提供了针对字符串比较的高级特性,格式为:[[expresion]] – 可以实现模式匹配
case命令

    使用case命令可以在一些时刻代替繁琐的if-then嵌套

格式:
case variable in
pattern1 | pattern2) commands1;;
pattern3) command2;;
*) default commands;;
esac

case名利你个会将指定的变量与不同模式进行比较。如果变量和模式是匹配的,那么shell会执行为该模式指定的命令 。可以通过竖线操作符在一行中分隔出多个模式。星号会捕获所有与已知模式不匹配的值。

for命令

    bash shell提供的for命令,允许创建一个遍历一系列值的循环。每次迭代都使用其中一个值来执行已定义好的一组命令。

格式:
for var in list
do 
	commands
done

// for var in list; do
		commands
	done

    list参数是需要用到的一系列值。在每次迭代中,变量var会包含列表中的当前值。第一次迭代会使用列表中的第一个值,第二次迭代使用第二个值,以此类推,直到列表中的所有值都过一遍。在do和done语句之间输入的命令可以是一条或多条标准的bash shell命令。在这些命令中,$var变量包含着这次迭代对应的当前列表项中的值。
    list参数的指定可以有以下几种方式实现:

  • 读取列表中的值,以空格隔开
    循环遍历
  • 读取列表中的复杂值,对于列表中的单引号可以使用转义字符(反斜线)来将单引号转义,或者使用双引号来定义用到单引号的值。在单独的数据值中有空格,就必须使用双引号将这些值圈起来
    在这里插入图片描述
  • 从变量读取列表,将一系列值存储在一个变量中,然后将变量传入for循环list参数
  • 从命令读取值,用命令替换来执行任何能产生输出的命令,然后在for命令中使用该命令的输出。
    在这里插入图片描述
  • 更改字段分隔符,默认情况下,bash shell会将下列字符当做字段分隔符:空格、制表符、换行符
  • 用通配符读取目录,可以使用for命令来自动遍历目录中的文件。进行此操作时,必须在文件名或路径名中使用通配符,它会强制shell使用文件扩展匹配。文件扩展匹配是生成匹配指定通配符的文件名或路径名的过程。
    文件遍历
C语言风格的for命令

    以下是bash中C语言风格的for循环的基本格式

for (( variable assignment ; condition ; interation process ))

    它与C语言的for循环有些许差别

  • 变量赋值可以有空格;
  • 条件中的变量不以美元符开头;
  • 迭代过程的算式未用expr命令格式。
  • 允许为迭代使用多个变量,循环会单独处理每个变量
    在这里插入图片描述
while命令

    while命令某种意义上来说就是if-then语句和for循环的混杂体。while命令允许定义一个要测试的命令,然后循环执行一组命令,只要定义的测试命令返回的是退出状态码0。它会在每次迭代的一开始测试test命令。在test命令返回非零退出状态码时,while命令会停止执行那组命令。

while test command
do
	other commands
done

    while命令中定义的test command和if-then语句中的格式相同,可以使用任何普通的bash shell命令,或者用test命令进行条件测试,比如测试变量值。
    while命令的关键在于所指定的test command的退出状态码必须随着循环中运行的命令而改变。如果退出状态码不发生改变,while循环就将一直不停地进行下去。
    最常见的test command的用法就是用方括号来检查循环命令中用到的shell变量的值。
在这里插入图片描述

    while命令允许在while语句行定义多个测试命令。只有最后一个测试命令的退出状态码会被用来决定什么时候结束循环。

until命令

    until命令与while命令工作的方式完全相反,until命令要求你指定一个通常返回非零状态码的测试命令。只有测试命令的退出状态码不为0,bash shell才会执行循环中列出的命令。一旦测试命令返回了退出状态码0,循环就结束了。

until test commands
do
	other commands
done

    和while命令类似,可以在until命令语句中放入多个测试没给你了那个,只有最后一个命令的退出状态码决定了bash shell是否执行已定义的other commands
在这里插入图片描述

控制循环

    使用以下两个命令可以控制循环内部的情况

  • break命令:break命令可以用来退出任意类型的循环,单层循环时跳出循环,多层循环时跳出所在的最内层循环,也可以指定层级,break 1表明跳出的是当前循环,break 2表示停止下一级的外部循环。
  • continue命令:continue命令可以提前中止某次循环中的命令,但并不会完全终止整个循环。也可以使用continue n定义要继续执行的循环层级。
外部循环

    在shell脚本中,可以对循环的输出使用管道或进行重定向,这可以通过在done命令后添加重定向来实现。重定向对象可以是生成文件或者是某些命令
在这里插入图片描述

循环编程小结

    for命令允许你遍历一系列的值,不管是在命令行里提供好的、包含在变量中的还是通过文件扩展匹配获得的文件名和目录名。
    while命令使用普通命令或测试命令提供了基于命令条件的循环。只有在命令(或条件)产生退出状态码0时,while循环才会继续迭代指定的一组命令。
    until命令也提供了迭代命令的一种方法,但它的迭代是建立在命令(或条件)产生非零退出状态码的基础上。这个特性允许设置一个迭代结束前都必须满足的条件。
    可以在shell脚本中对循环进行组合,生成多层循环。bash shell提供了continue和break命令,允许根据循环内的不同值改变循环的正常流程。
    bash shell还允许使用标准的命令重定向和管道来改变循环的输出,可以使用重定向来将循环的输出重定向到一个文件或另一个命令。

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值