Shell核心编程——第一章

1.1 脚本文件的书写格式

范例:
#!/bin/bash                  #指定解释器,系统决定使用的解释语言 <<COMMENT                 #<<多行注释,COMMENT可更换其他字符 Author: fangdong xiao
 Date: 2020-08-15
 Version: 1.0 Desciption:
COMMENT                   #前后对应才能有多行注释的效果 #单行注释
 echo “hello world”          #这是命令代码,也称脚本代码
注意:

1.脚本文件第一行要求使用shebang(#!)符号,指定一个脚本的解释器,如:#!/bin/bash, #!/bin/sh, #!/usr/bin/env python等,该行被注释,不会被当做命令执行!
2.多行注释的格式:
<<关键字    注释内容
关键字

1.2 脚本文件的各种执行方式

  执行脚本文件的方式有很多种,有需要执行权限的方式(./script.sh),有不需要执行权限的方式(bash等命令),有开启子进程的方式(bash等命令),有不需要开启子进程的方式(source).

1.2.1 脚本文件自身没有可执行权限
现象:      # ./script.sh             # 运行报错,权限不够
 解决方式:    # sudo chmod +x script.sh    # 分配可执行权限
 或更换执行方式: 1). # bash script.sh      2). # sh script.sh
1.2.2 脚本文件自身有可执行权限
1). # bash script.sh   
2). # sh script.sh3). # ./script.sh
1.2.3 开启子进程执行的方式

注:一般可以通过pstree命令来查看进程树,了解进程直接的关系 解释:使用pstree命令,会发现计算机启动的第一个进程是systemd,然后在这个进程下启动了N个子进程。其实使用bash,sh等,都是在这个进程下的子进程。

1.2.4 不开启子进程执行的方式

解释:使用source 或 . (点)命令来执行脚本,则在使用pstree会发现,会出现一个与systemd同等级的一个进程!

请自行到真机上做测试!!!

1.3 如何在脚本文件中实现数据的输入与输出(echo、printf)

1.3.1 使用echo命令显示输出

功能描述:echo命令主要用来显示字符串信息。
echo语法格式:echo [选项] 字符串 使用参数:-e 解析下面的特殊符号!echo -e “字符串”


表1-3-1 常见转义符号及功能描述

符号

功能描述

案例

\b

退格键(Backspace)

# echo -e “helle\bo world”

# 结果:hello world

\f

换行但光标仍停留在原来的位置

# echo -e “hello\fworld”

# 结果:hello 换行后world

\n

换行且光标移至行首

# 同上类似格式

\r

光标移至行首,但不换行

# 同上类似格式

\t

插入Tab键

# 同上类似格式

\

打印\

# 同上类似格式

\033 或 \e

设置终端属性,如字体颜色、背景颜色、定位光标等

# echo -e “\033[1mOK\033[0m”

# 结果:OK会加粗

# echo -e “\e[1mOK\e[0m”

# 结果:同上

echo的重定向:

# echo “hello world" > hello.txt   # 将字符串写入文件中,且会覆盖原来内容
# echo “hello world" >> hello.txt # 将字符串写入文件中,不会覆盖原来内容
1.3.2 使用printf命令显示输出

备注:一般printf 命令的参数就会指示需要输出对应格式的内容!


表1-3-2 常用格式字符串及功能描述

格式字符

功能描述

应用案例

%d 或 %i

十进制整数

# printf “%d” 12

%o

八进制整数

# printf “%o” 10

%x

十六进制整数

# printf “%x” 10

%u

无符号十进制整数

# printf “%u” 10

%f

浮点数(小数点数)

# printf “%f” 6.600000

# printf “%.3f” 6.600

%s

字符串

# printf “%s” “hello”

\b

退格键

\f

换行但光标仍停留在原来的位置

\n

换行且光标移至行首

\r

光标移至行首,但不换行

\t

Tab键

1.3.3 使用read命令读取用户的输入

功能描述:read命令可以从标准输入读取一行数据
read 命令语法格式:read [选项] [变量名] 注:如未指定变量名,则默认变量名称为REPLY。


表 1-3-3 read命令的选项

选项

功能

-p

显示提示信息

-t

设置读入数据的超时时间

-n

设置读取n个字符后结束,而默认会读取标准输入的一整行内容

-r

支持读取 \ ,而默认read命令理解 \ 为特殊符号(转义字符)

-s

静默模式,不显示标准输入的内容(Silent mode)

应用实例:

# read key_input   # 回车后键盘输入一串字符串,再回车,即可使用echo $key_input 输出内容
# read key1 key2 key3   # 从标准输入读取3组字符串,每组空格分开
# read -p "请输入用户名:" user   # 设置一个提示信息
# read -s -p "请输入密码:" pass   # 加了-s参数,不显示输入内容,反之,显示

1.3.4 输入和输出的重定向

在Linux系统中输出可以分为标准输出和标准错误输出。标准输出的文件描述符为1,标准错误输出的文件描述符为2。而标准输入的文件描述符则为0。重定向符号:

  1. > 新建或覆盖
  2. >> 新建或追加

重定向组合:

>1>2>&>2>&11>&2>>1>>2>>&>>2>>&11>>&2<1<2<&<2<&11<&2<<1<<2 <<&<<2<,&11<<&2

使用格式:(只列出覆盖重定向,追加重定向原理相同 )

  1. ls /home/ 1> users.txt 等同于 ls /home/ > users.txt 因为默认 1> 为 >,可忽略不写
  2. ls /nofile/ 2> error.txt 因为不存在nofile文件夹,所有会报错,且将报错重定向到文件中
  3. ls -l /etc/hosts /nofile > ok.txt 2> error.txt 分别将正确和错误信息重定向到不同文件中
  4. ls -l /etc/hosts /nofile &> test.txt 将标准输出和错误输出重定向到同一个文件中
  5. ls /nofile 2>&1 特殊一点,将标准错误输出重定向到标准正确输出上显示出来
  6. ls /etc/hosts 1>&2 同上原理
  7. ls /etc/hosts /nofile > test.txt 2>&1,根据上面介绍的原理,即可实现将错误和正确信息重定向到一个文件中
1.3.5 Linux系统 “黑洞”

Linux 系统中有一个特殊的设备:/dev/null ,这是一个黑洞。无论往该文件中写入多少数据,都会被系统吞噬、丢弃注: 数据一旦导入黑洞将无法找回。

# echo “hello” > /dev/null
 # ls /nofile 2> /dev/null
 # ls /etc/hosts /nofile &> /dev/null

1.4 各种引号的正确使用姿势

各种引号: 双引号("") 单引号('') 反引号 (``) 转义符号( \ )   组合符号( $() )

1.4.1 单引号与双引号

单引号(''):引用的内容为一个整体,且屏蔽特殊符号的含义

# echo ###       # 默认输出空行,因为#为注释符号
# echo '###'     # 输出###,因为屏蔽了特殊含义

双引号(""):引用的内容为一个整体,不屏蔽特殊符号的含义

# echo ###       # 默认输出空行,因为#为注释符号
# echo "###"     # 结果同上
1.4.2 反引号

反引号 (``):一个命令替换符号,即反引号里面的命令运行后的结果代替命令

# tar -czf /root/log.tar.gz /var/log/  # 将log目录打包备份到root下面,且名字固定为log.tar.gz,每日备份则会复制原日志
# tar -czf /root/log-`date +%Y%m%d`.tar.gz  /var/log/

注:反引号虽好用,但也有其自身缺陷,比如易于跟单引号混淆,不支持嵌套。(为了解决这个问题,又有了$()组合符号)

1.4.3 组合符号

组合符号( $() ):与反引号功能相同,它解决了反引号的一些缺陷

# tar -czf /root/log-&(date +%Y%m%d).tar.gz  /var/log/    # 使用组合符号代替反引号
# echo "当前系统进程数量:$(ps aux | wc -l) "
# echo $(echo 我是1级嵌套 $(echo 我是2级嵌套))

1.5 变量

在Linux中,变量分为系统预设变量和用户自定义变量

1.5.1 变量命名规则

自定义变量的变量名仅可以使用字母、数字、下划线的组合,且不能数字开头

1.5.2 变量赋值

定义&赋值:变量名=值       # test=123 等号左右两边不能有空格
取消定义:unset 变量名      # unset test 调用变量:echo ${变量名}     # echo ${test}

1.5.3 系统预设变量

变量名

描述

UID

当前账户的账户ID号

USER

当前账户的账户名称

HISTSIZE

当前终端的最大历史命令条目数量(最多可以记录多少条历史命令)

HOME

当前账户的根目录

LANG

当前环境使用的语言

PATH

命令搜索路径

PWD

返回当前工作目录

RANDOM

随机返回0至32767的整数

$0

返回当前命令的名称($0、$1、$2、等,也叫位置变量)

$N

返回位置参数,如$1(第一个位置参数)、$2等,数字大于9时必须使用 ${n}

$#

命令参数的个数

$*

命令行的所有参数,“$*”所有的参数作为一个整体

#@

命令行的所有参数,“$@“所有的参数作为独立的个体

#?

返回上一条命令退出时的状态码(一般,0代表正确,非0代表失败)

#$

返回当前进程的进程号

$!

返回最后一个后台进程的进程号

注:系统预设变量可以细分为:环境变量、位置变量、预定义变量、自定义变量。

1.6 数据过滤与正则表达式

工作中经常需要使用脚本对数据进行过滤和筛选工作。

1.6.1 数据过滤

Linux提供了一个非常方便的grep命令,可以实现过滤功能。

描述:grep命令可以查找关键词并打印匹配的行。用法:    grep [选项] 匹配模式 [文件] 。    grep [-acinv] [--color=auto] '搜寻字符串' filename常用选项:    -a   将 binary 文件以 text 文件的方式搜寻数据    -c   计算找到 '搜寻字符串' 的次数    -o   仅显示匹配内容,而不显示全行所有内容    -i   忽略字母大小写    -v   取反匹配    -w   匹配单词    -q   静默匹配,不将结果显示在屏幕上    --color=auto   可以将找到的关键词部分加上颜色的显示喔!(默认启用了)

案例:

# grep th test.txt         # 在test.txt文件中过滤包含th关键词的行
# grep -i the test.txt      # 过滤包含the关键词的行(不区分大小写)
# grep -w num test.txt      # 仅过滤num关键词(不会过滤number关键词)
# grep -v the test.txt      # 过滤不包含the关键词的行
# grep -q root /etc/passwd   # 不在屏幕上显示过滤的结果
1.6.2 基本正则表达式(Basic Regular Expression)


表1-6-2 基本正则表达式及其含义

字符

含义

c

匹配字母c

.

匹配任意单个字符

*

匹配前一个字符出现零次或多次

.*

匹配多个任意字符

[]

匹配集合中的任意单个字符,括号可以是任意数量字符的集合

[x-y]

匹配连续的字符串范围

^

匹配字符串的开头

$

匹配字符串的结尾

[^]

匹配否定,对括号中的集合取反

\

匹配转义后的字符串

\{n,m\}

匹配前一个字符重复n到m次

\{n,\}

匹配前一个字符重复至少n次

\{n\}

匹配前一个字符重复n次

\(\)

将\(与\)之间的内容存储在“保留空间”,最多可存储9个

\n

通过\1至\9调用保留空间中的内容

注:根据不同系统可能会存在一些小差异
案例:

# grep “^$” /etc/passwd             # 过滤文件空白行
# grep "sbin/[^n] " /etc/passwd    # 查找sbin/后面不跟 n 的行
# grep "0\{1,2\}" /etc/passwd     # 查找数字 0 出现最少1次,最多2次的行
# grep "[0-9f-q]" /etc/passwd     # 查找包含0-9或 f-q 字符的行
1.6.3 扩展正则表达式(Extend Regular Expression)


表1-6-3 扩展正则表达式及其含义

字符

含义

{n,m}

等同于基本正则表达式的\{n,m\}

+

匹配前的字符出现一次或多次

?

匹配前的字符出现零次或一次

|

匹配逻辑或,即匹配

( )

匹配正则集合,同时也有保留的意思,等同于基本正则表达式的\( \)

注:grep默认不支持正则表达式,需要使用grep -E 或者使用egrep命令进行扩展正则表达式的过滤
案例:

# egrep "0{1,2}" /etc/passwd        # 查找数字0出现最少1次最多2次的行
# egrep "0+" /etc/passwd           # 查找包含至少一个0的行
# egrep "(root|admin)" /etc/passwd    # 查找包含root或者admin的行
1.6.4 POSIX 规范的正则表达式

解释:由于基本正则表达式会有语系问题,所有这里需要了解POSIX规范的正则表达式规则。它可以解决语系问题,也比较接近自然语言!


表1-6-4 POSIX规范字符集

字符集

含义

字符集

含义

[:alpha:]

字母字符

[:graph:]

非空格字符

[:alnum:]

字母与数字字符

[:print:]

任意可以显示的字符

[:cntrl:]

控制字符

[:space:]

人亦可以产生空白的字符

[:digit:]

数字字符

[:blank:]

空格与Tab键字符

[:xdigit:]

十六进制数字字符

[:lower:]

小写字符

[:punct:]

标点符号

[:upper:]

大写字符

注:Linux运行通过方括号使用POSIX标准规范,如[[:alnum:]]将匹配任意单个字母数字字符。
案例:

# grep "[[:digit:]]" /etc/passwd    # 列出包含数字字符的行
# grep "[[:alpha:]]" /etc/passwd    # 列出包含字母字符的行
# grep "[[:space:]]" /etc/passwd    # 列出任意可以产生空白的行,如:下划线 " _ "

1.7 各式各样的算术运算

Shell 支持多种算术运算,可以使用$((表达式))、 $[表达式]、let表达式进行整数的算术运算,注意这些命令无法执行小数运算;使用bc命令可以进行小数运算。

1.7.1 算术运算


表1-7 常用运算符号

运算符号

含义描述

运算符号

含义描述

++

自加1


自减1

+

加法

-

减法

*

乘法

/

除法

**

求幂

%

取余(取模)

+=

自加任意数

-=

自减任意数

*=

自乘任意数

/=

自除任意数

||

逻辑或

&&

逻辑与

>

大于

>=

大于等于

<

小于

>=

小于等于

%=

对任意数取余

表达式?表达式:表达式

根据表达式结果,返回特定的值

案例:

# echo $((2+4))   #得6           # x=6;y=8;echo $[x>y?2:4]   #得4,如果x大于y,返回2,否则返回3.
# x=2;y=3;echo $((x*y))   #得6     # echo $((2>1&&3>4))  # 仅当&&两边表达式为真时,返回1;此时返回0
# echo $[(1+2)*3]   # 得9,注意优先级   # echo $((2**4))  # 2的4次幂得16
1.7.2 内置命令let

注:使用let命令计算时,默认不会输出运算结果,一般需要赋值给变量,通过变量查看运算结果。且变量前不要加 $ 符号。
案例:

# x=1;let x++;echo $x;   # x=x+1;得2        # let i=(1+2)*3;echo $i  # 得9
# let 2.2+2.5;       # 报错,let无法进行小数运算
1.7.2 bc计算器

Bash 仅支持对整数的四则运算,不支持对小数的运算。当需要小数运算时,可使用bc计算器。
bc计算器支持交互和非交互式两种执行方式。

在交互式环境下使用 bc

1.使用 bc 进行数学计算是非常容易的,像平常一样输入数学表达式,然后按下回车键就可以看到结果。
2.bc支持变量
3.支持函数、循环结构、分支结构等常见的编程元素,它们和其它编程语言的语法类似。



内置变量

变量名

作 用

scale

指定精度,也即小数点后的位数;默认为 0,也即不使用小数部分。

ibase

指定输入的数字的进制,默认为十进制。

obase

指定输出的数字的进制,默认为十进制。

last 或者 .

表示最近打印的数字

注:obase 要尽量放在 ibase 前面,因为 ibase 设置后,后面的数字都是以 ibase 的进制来换算的。



内置函数

函数名

作用

s(x)

计算 x 的正弦值,x 是弧度值。

c(x)

计算 x 的余弦值,x 是弧度值。

a(x)

计算 x 的反正切值,返回弧度值。

l(x)

计算 x 的自然对数。

e(x)

求 e 的 x 次方。

j(n, x)

贝塞尔函数,计算从 n 到 x 的阶数。

案例:

# echo "scale=4;3*8/7"|bc # 得3.4285
# ret=$(echo "4+9"|bc; echo $ret  # 得13
# x=4; echo "scale=5;n=$x+2;e(n)"|bc -l  # 得403.42879 , 使用变量
#m=31; n=$(echo "obase=16;$m"|bc); echo $n  # 得1F,十进制转十六进制

借助输入重定向使用 bc 计算器

variable=$(bc << EOF
 expressions
 EOF
 )


其中,variable是 Shell 变量名,express是要计算的数学表达式(可以换行,和进入 bc 以后的书写形式一样),
EOF是数学表达式的开始和结束标识(你也可以换成其它的名字,比如 aaa、bbb 等)。

·
·
·
·
·
·
·
·
·


匠心制作