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>
&>
2>&1
1>&2
>>
1>>
2>>
&>>
2>>&1
1>>&2
<
1<
2<
&<
2<&1
1<&2
<<
1<<
2 <<
&<<
2<,&1
1<<&2
使用格式:(只列出覆盖重定向,追加重定向原理相同 )
ls /home/ 1> users.txt 等同于 ls /home/ > users.txt
因为默认 1> 为 >,可忽略不写ls /nofile/ 2> error.txt
因为不存在nofile文件夹,所有会报错,且将报错重定向到文件中ls -l /etc/hosts /nofile > ok.txt 2> error.txt
分别将正确和错误信息重定向到不同文件中ls -l /etc/hosts /nofile &> test.txt
将标准输出和错误输出重定向到同一个文件中ls /nofile 2>&1
特殊一点,将标准错误输出重定向到标准正确输出上显示出来ls /etc/hosts 1>&2
同上原理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 等)。
·
·
·
·
·
·
·
·
·
匠心制作