Shell核心编程——第一章《纯干货》

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.sh
3). # ./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光标移至行首,但不换行
\tTab键
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/   # 将date运行输出后的结果作为文件名的一部分,即可实现每日备份

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

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 等)。

·
·
·
·
·
·
·
·
·

匠心制作
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值