《Linux Shell脚本攻略》学习笔记-第一章

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

1.1 简介

计算机可以从文本文件称为shell脚本中读取并执行命令。

sehll脚本不仅节省了时间而且清楚明白地表明了所执行的操作。

bash shell变成了UNIXLinux中既成事实的标准shell

1.2 在终端中显示输出

1

$表示普通用户#表示管理员用户root

推荐使用普通用户登录系统然后借助sudo这类工具来运行特权命令其执行命令的效果和root一样。

2

shell脚本通常以shebang起始。

#!/bin/bash

其中#位于解释器路径之前/bin/bash是bash的解释器命令路径。

脚本中只有第一行可以使用shebang来定义解释该脚本所使用的解释器。

脚本执行的两种方式

bash 文件名.sh

chmod 755 文件名.sh

./文件名.sh

如果将脚本作为bash的命令行参数来运行那么就不需要使用shebang了。

内核会读取脚本的首行并注意到shebang为#!/bin/bash他会识别出/bin/bash并执行该脚本。

3

~表示主目录通常为/home/user其中uesr是用户名。

$cmd1 ; cmd2 等同于$cmd1 $cmd2

4

ehco是用于终端打印的最基本命令默认情况下echo在每次调用后会添加一个换行符。可以使用-n来禁止echo在文本的末尾追加换行符。

双引号允许shell解释字符串中出现的特殊字符单引号不会对其做任何解释。

在使用转义序列时需要使用echo -e“包含转义序列的字符串”这种形式。

打印彩色文本输出

5

printf命令接受 引用文本或由空格分隔的参数。我们可以在printf中使用格式化字符串来指定字符串的宽度、左右对齐方式等。

默认情况下printf并不会自动添加换行符。

%s,%c,%d,%f都是格式替换符它们定义了该如何打印后续参数。

6

文本颜色0,30-37

彩色背景0,40-47

 

1.3 使用变量与环境变量

和编译型语言不同大多数脚本语言不要求在创建变量之前声明其类型在变量名前面加上一个美元符号就可以访问到变量的值。

常用的惯例是在脚本中使用大写字母命名环境变量使用驼峰命名法或者小写字母命名其他变量。

1查看全部环境变量

使用env或者printenv命令查看当前shell中所定义的全部环境变量。

查看其他进程的环境变量其中PID是相关进程的进程ID使用pgrep命令获取进程ID。

2

     var = value等号两边加上空格表示的是等量测试关系。

     var=value等号两边没有空格是赋值操作符。

3

因为shell使用空白字符来分隔单词所以我们需要加上一对花括号来告诉shell这里的变量名是fruit而不是fruits。

4

使用单引号时变量不会被扩展仍旧照原样显示使用双引号就会显示出变量的值如果没有定义过则什么都不显示。

5

环境变量UID中保存的是用户ID。它可以用于检查当前脚本时以root用户还是以普通用户的身份运行的。

root用户的UID0

1.4 使用函数添加环境变量

这个例子展示了如何将新的路径添加到环境变量的起始部分。

[ -d "$2" ]判断第二个函数指定的目录是否存在

如果存在eval表达式将第一个参数所指定的变量值设置成第二个参数的值加上随后再跟上第一个参数的原始值。

${parameter:+expression}:如果parameter有值且不为空则使用expression的值。

1.5 使用shell进行数学运算

bash shell使用let、(( ))和[ ]执行基本的算术操作。

工具expr和bc可以用来执行高级操作。

1let命令可以用来直接执行基本的算术操作。当使用let时变量名之前不需要再添加$。

2操作符[]的使用方法和let命令一样也可以在[]中使用$前缀。

3也可以使用操作符(( ))出现在(( ))中的变量名之前需要加上$

4expr命令也可以执行基本算术操作算术符号的前后一定要有空格

以上这些方法只能用于整数运算不支持浮点数。

5bc是一种用于数学运算的高级使用工具可以借助它执行读点书运算并使用一些高级函数。

根据在线手册bc对于加减乘三种算法依据输入中的最高精度来确定输出精度不会进行自行截断此时scale设置无效。解决方法可以使用printf来控制输出精度但是除法则相反可以通过设置scale来设置精度。

其中obase是转换后的进制ibase是转换前的进制

1.6 玩转文件描述符与重定向

文件描述符是与输入和输出流相关联的整数。最广为人知的文件描述符是stdin、stdout和stderr。

脚本可以使用大于号将输出重定向到文件中。命令产生的文本可能是正常输出也可能是错误信息。

正常输出和错误信息都会显示在屏幕上我们可以分别为其指定特定的文件描述符来区分两者。

0

stdin 标准输入

1

stdout 标准输出

2

stderr 标准错误

其中命令成功执行后退出状态为0发生错误会返回一个非0的退出状态。

标准错误一般不会重定向到文件中

方法

stdout作为单数据流可以被重定向到文件或是通过管道传入其他程序但是两者无法兼得。

有一种方法tee既可以将数据重定向到文件又可以提供一份重定向数据的副本作为管道中后续命令的stdin。

默认情况下tee命令将文件覆盖但是它提供了一个-a选项可用于追加内容。

借助小于号我们可以像使用stdin一样从文件中读取数据。

出现在cat <<_EOF_ > cat.txt与下一行_EOF_之间的所有文本行都会被当做stdin数据。

cat.txt文件的内容显示如下

exec命令创建全新的文件描述符。<操作符可以将文件读入stdin>操作符用于截断模式的文件写入>>操作符用于追加模式的文件写入。

1.7 数组与关联数组

bash支持普通数组和关联数组前者使用整数作为数组索引后者使用字符串作为数组索引。

1.8 别名

别名是一种便捷方式可以为用户省去输入一长串命令序列的麻烦。

字符\可以转义命令从而执行原本的命令。在不可信的环境下执行特权命令时在命令前加上\来忽略可能存在的别名总是一种良好的安全实践。

1.9  采集中断信息

tput和stty是两款终端处理工具。

stty命令的选项-echo禁止将输出发送到终端而选项echo则允许发送输出。

1.10 获取并设置日期及延时

在系统内部日期被存储成一个整数其取值为从1970年1月1日0时0分0秒起所流逝的秒数。这种纪元方式称为纪元时或者Unix时间。

sleep命令可以延迟脚本执行一段时间以秒为单位。

1.11 调试脚本

运行带有-x选项的脚本可以打印出所执行的每一行命令及当前状态。

set -x

在执行时显示参数和命令

set +x

禁止调试

set -v

当命令进行读取时显示输入

set +v

禁止打印输入

export PS4='$LINENO:'调试时显示每行的行号。

调试时使用-x或者set -x选项调试输出会被发送到stderr。

1.12 函数和参数

最大的差异在于函数参数可以在函数体中任意位置上使用而别名只能将参数放在命令尾部。

$0是脚本名称$n是第n个参数"$@"被扩展成"$1""$2""$3""$*"被扩展成"$1c$2c$3",其中cIFS的第一个字符。

函数也能像环境变量一样使用export导出如此一来函数的作用域就可以扩展到子进程中。

1.13 将一个命令的输出发送给另一个命令

一个命令的输出可以作为另一个命令的输入而这个命令的输出又会传递至下一个命令以此类推。

我们使用管道连接每个过滤器管道的操作符是 | 。

cmd1的输出传递给cmd2cmd2的输出传递给cmd3最终的输出会出现在显示器中或者被导入某个文件。

子shell是一个独立的进程可以使用操作符来定义一个子shell。

当命令在子shell中执行时不会对当前shell造成任何影响所有的改变仅限于该子shell内。

假设我们使用子shell或者反引号的方法将命令中的输出保存到变量中为了保留输出的空格和换行符必须使用双引号。存疑

1.14 在不按下回车键的情况下连续读入n个字符

bash中的read命令能够从键盘或者标准输入中读取文本。编程语言的大多数输入库都是从键盘读取输入当回车键按下的时候标志着输入完毕。

但有时候没发按回车键输入结束与否是由读取到的字符数或某个特定字符来决定的。

read -t有其特殊性结束后会自动在命令行中显示输入的值若是接下来还有read可能将其作为一种输入。

1.15 持续运行命令直至执行成功

该循环执行以函数参数形式$@传入的命令。如果命令执行成功则返回进而退出循环。

true是作为/bin中的一个二进制文件来实现的。这意味着每执行一次之前提到的while循环shell就不得不生成一个进程。

为了避免这种情况可以使用shell的内建命令该命令的退出状态总是0。

1.16 字段分隔符与迭代器

内部字段分隔符IFS是shell脚本中的一个重要概念。IFS是一个环境变量其中保存了用于分隔的字符它是当前shell环境使用的默认定界字符串。

IFS的默认值是空白字符换行符、制表符或者空格

当条件为真时while循环继续执行当循环条件为假时until循环继续执行。

用true作为循环条件可以产生无线循环。

1.17 比较与测试

程序中的流程控制是由比较语句和测试语句处理的。我们可以使用if、if else以及逻辑运算符来测试用比较运算符来比较数据项。

除此之外还有一个test命令可以用于测试。

&&如果condition为真则执行action

||如果condition为假则执行action

一定要注意运算符、比较复[ ]与操作数之间的空格否则可能达不到想要的效果或者报错。

-a-o放在[[ ]]中会报错

我们可以使用不同的条件标志测试各文件系统的相关属性。

根据ASCII值进行比较。

使用test命令可以避免使用过多的括号增强代码的可读性。

但是test命令的执行效率要低于括号因为test是外部程序而括号是内建命令。

解决方法

1.18 使用配置文件定制bash

Linux中能够放置定制脚本的文件不止一个。这些配置文件分为三类登录时执行的、启动交互式shell时执行的、调用shell处理脚本文件时执行的。

  • test命令
  • 字符串比较
  • 文件系统相关测试
  • 算术比较
  • 逻辑与、逻辑或
  • if、if else使用方法
  • 循环
  • 实战练习
  • 改变默认IFS
  • 加入延时sleep
  • 一种更快的做法
  • 通过子shell的方式保留空格和换行符
  • 利用子shell生成一个独立的进程
  • 将命令序列的输出赋值给变量
  • 管道
  • shift命令可以将参数依次向左移动一个位置让脚本能够使用$1来访问每一个参数。
  • 读取命令的返回值
  • 递归函数在bash中函数同样支持递归调用可以调用自身的函数
  • 导出函数
  • 函数参数可以按照位置访问。
  • 函数定义和执行的方式
  • 补充知识
  • 使用set -v和set +v可以对脚本输入进行部分调试
  • 使用set -x和set +x可以对脚本进行部分调试
  • bash -x启用shell脚本的跟踪调试功能
  • 在脚本中加入延时
  • date命令所支持的格式选项
  • 计算一段shell脚本所使用的的执行时间
  • 常用日期命令
  • stty
  • tput
  • 转义字符 \
  • 查看当前环境中定义的所有别名
  • alias命令的效果只是暂时的。一旦关闭终端所有设置过的别名都会失效。想要使别名在所有的shell中都可用可以将其定义为放入~/.bashrc文件中。
  • 删除别名只需要将对应的定义从~/.bashrc文件中删除或者使用unalias命令也可以使用alias 别名=。
  • 创建别名alias
  • 关联数组当使用字符串作为索引时关联数组要比数字索引数组更容易使用。
  • 打印数组的长度
  • 以列表形式打印出所有的值
  • 打印出特定索引的数组元素内容
  • 定义数组的方法
  • 自定义文件描述符
  • 重定向脚本内部的文本块
  • 将文件重定向到命令
  • 标准错误重定向
  • 在命令行结束后立即执行echo $?就可以打印出退出状态。
  • 使用大于号将文本保存到文件中使用双大于号将文本追加到文件中。
  • 计算平方及平方根
  • 进制转换
  • 设定小数精度
  • 检查当前用户是否为超级用户
  • 识别当前所使用的的shell$SHELL或者$0
  • 获取字符串长度${#变量名}
阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: shelllinux