Shell学习笔记

本文详细介绍了Shell脚本的基础知识,包括Shell解析器、变量(系统变量、特殊变量、自定义变量)、运算符、条件判断、流程控制(if、case、for、while)以及函数。讲解了如何定义、使用和操作变量,演示了各种运算符的用法,并通过实例展示了条件判断和流程控制结构。此外,还探讨了数组、Shell工具如cut、sed、awk和sort的使用,以及如何创建和使用自定义函数。内容深入浅出,适合初学者和进阶者学习。

目录

一、概述

1. 简介

2. 入门

3. Shell解析器

二、变量

1. 系统变量

2. 特殊变量

3. 自定义变量

(1)定义与撤销变量

(2)声明只读变量(静态)

(3)数组

三、运算符

1. 语法

(1)表达式区域

(2)运算符

2. 实例

四、条件判断

1. 语法

2. 判断符号

五、流程控制

1. if 与 case

(1)if

(2)case

2. for 与 while

(1)for

(2)while

3. 括号问题

七、函数

1. 系统函数

(1)basename获取文件的名称

(2)dirname获取文件的路径

2. 自定义函数

(1)语法

(2)实例

*六、Shell工具

1. cut

2. sed

3. awk

4. sort


一、概述

1. 简介

  • Shell是一个命令解释器,用于接受应用程序或用户的命令,调用操作系统内核。
  • 与此同时,Shell也可以认为是一种编程语言,其内容可以由linux命令组成。

2. 入门

  • Shell文件可以以 .sh 结尾,也可以不写;
  • Shell文件一般在第一行写#!/bin/bash,用于指定shell脚本的解析器;
  • shell脚本的执行方式:
    • 可以使用sh或bash命令执行文件;
    • 赋予shell文件执行权限,然后直接使用shell文件执行;
[root@docker data]# ll
总用量 4
-rw-r--r--. 1 root root 33 4月  16 23:13 ex.sh
[root@docker data]# 
[root@docker data]# ll
总用量 4
-rw-r--r--. 1 root root 33 4月  16 23:13 ex.sh
[root@docker data]# cat ex.sh 
#!/bin/bash

echo "This is test"
[root@docker data]# sh ex.sh 
This is test
[root@docker data]# bash ex.sh 
This is test
[root@docker data]# chmod 744 ex.sh 
[root@docker data]# ll
总用量 4
-rwxr--r--. 1 root root 33 4月  16 23:13 ex.sh
[root@docker data]# ./ex.sh
This is test
[root@docker data]# pwd
/root/data
[root@docker data]# /root/data/ex.sh
This is test
[root@docker data]# 

3. Shell解析器

  • Linux中包含很多Shell解析器,如下所示:

  • CentOS中默认的解析器是bash,而sh其实是bash的软连接:

二、变量

1. 系统变量

// 家目录
[root@docker data]# echo $HOME
/root

// 当前目录
[root@docker data]# echo $PWD
/root/data

// 默认是Shell解析器
[root@docker data]# echo $SHELL
/bin/bash

// 当前用户
[root@docker data]# echo $USER
root

2. 特殊变量

$n

n为数字,其中$0便是脚本名称,$1~9表示对应变量,如果n大于10则需写成$[10]

$#

表示参数个数

$*

表示所有参数,当以""括起来时,代表所有参数整体,一个变量

$@

表示所有参数,当以""括起来时,还是代表每个参数

$?

返回命令执行的结果,执行成功或输出结果为True,则$?结果为0,否则为其他数字

$$

脚本运行时的pid

3. 自定义变量

(1)定义与撤销变量

  • shell中变量默认为字符型
  • 变量的种类:
    • 静态:k="v"或k='v'或k=v
    • 动态:k=`v` : v是变量 v系统自带的命令
  • 引用方式:$变量名或${变量名}
【注意:=左右不能有空格】
[root@docker data]# a=1
[root@docker data]# echo $a
1

// 撤销变量
[root@docker data]# unset a
[root@docker data]# echo $a

[root@docker data]# 

(2)声明只读变量(静态)

[root@docker data]# readonly a=2
[root@docker data]# echo $a
2

// 只读变量无法被撤销,重启主机后将失效
[root@docker data]# unset a
-bash: unset: a: 无法反设定: 只读 variable

// 如果参数值包含空格则需要使用引号
[root@docker data]# b="1 2 3"
[root@docker data]# echo $b
1 2 3

//参数默认都是字符型,无法直接进行数值运算
[root@docker data]# c=2
[root@docker data]# echo $a+$c
2+2

(3)数组

语法格式:arr=(v1 v2 ... vn) //数组用()表示且元素使用空格分隔

[root@docker data]# vim arr.sh
[root@docker data]# cat arr.sh 
#/bin/bash

arr=(1 2 3 4)
echo "所有元素 : ${arr[@]}"
echo "第一个元素 : ${arr[0]}"
echo "元素个数 : ${#arr[@]}"
[root@docker data]# bash arr.sh 
所有元素 : 1 2 3 4
第一个元素 : 1
元素个数 : 4

三、运算符

1. 语法

(1)表达式区域

  • $((运算式))
  • $[运算式]
  • expr 运算式【注意:此方式数值及符号间需要有空格】

(2)运算符

  • + , - , \*, /, % // 加,减,乘,除,取余

2. 实例

// expr 加法 
[root@docker data]# expr 1 + 2
3

// expr 乘法 注意*前需要加\
[root@docker data]# expr 2 \* 2
4

// 混合运算 注意需要使用`
[root@docker data]# expr `expr 2 \* 2` + 1
5

// $(()) 方式 注意需要写echo
[root@docker data]# echo $((2*2+1))
5

// $[] 方式 注意需要写echo
[root@docker data]# echo $[2*2+1]
5

四、条件判断

1. 语法

[条件] :条件只要非空结果即为true,否则为false;

【注意:条件前后需要有空格】

[root@docker data]#  [ ] 
[root@docker data]# echo $?
1
[root@docker data]#  [ s ]
[root@docker data]# echo $?
0

2. 判断符号

=

字符串比较

整数比较

-lt

小于

-le

小于等于

-gt

大于

-ge

大于等于

-eq

等于

-ne

不等于

文件权限判断

-r

有读权限

-x

有执行权限

-w

有写权限

文件类型判断

-f

文件存在是一个常规文件

-e

文件存在

-d

文件存在是一个文件夹

[root@docker data]# ll
总用量 12
-rwxrwxrwx. 1 root root  33 4月  16 23:29 aa.sh
-rw-r--r--. 1 root root 132 4月  17 00:43 arr.sh
-rw-r--r--. 1 root root 132 4月  16 23:49 test1.sh
[root@docker data]# [ -f aa.sh ]
[root@docker data]# echo $?
0
[root@docker data]# [ 2 -gt 3 ]
[root@docker data]# echo $?
1

五、流程控制

1. if 与 case

(1)if

[root@docker data]# vim if.sh
[root@docker data]# cat if.sh 
#/bin/bash

if [ $1 -eq 1 ];then
echo "该值等于1"
elif [ $1 -eq 2 ]
then
echo "该值等于2"
fi

[root@docker data]# bash if.sh 1
该值等于1
[root@docker data]# bash if.sh 2
该值等于2

注意:

  • [] 内条件前后需要有空格;
  • then如果写在if后面需要写分号,换行则不用;
  • 最后结尾需要写fi;

(2)case

该语法类似于switch

[root@docker data]# vim case.sh
[root@docker data]# cat case.sh 
#/bin/bash


case $1 in
1)
	echo "这个值是1"
;;
2)
	echo "这个值是2"
;;
*)
	echo "这个值不是1或2"
;;
esac
[root@docker data]# sh case.sh 1
这个值是1
[root@docker data]# sh case.sh 2
这个值是2
[root@docker data]# sh case.sh 3
这个值不是1或2

注意:

  • 条件后需要写in;
  • 匹配条件后需要写);
  • 每个业务语句后需要些 ;; 终止case
  • 最后结尾需要写esac;

2. for 与 while

(1)for

[root@docker data]# vim for.sh
[root@docker data]# cat for.sh 
#!/bin/bash

s=0
for((i=0;i<=100;i++))
do
	s=$[$s+$i]
done
echo $s
[root@docker data]# sh for.sh 
5050

// 另一种for循环,直接遍历数组
[root@docker data]# vim for2.sh
[root@docker data]# cat for2.sh 
#!/bin/bash

for i in $*
do
	echo "参数: $i"
done

for i in $@
do
	echo "参数: $i"
done

for i in "$*"
do
        echo "参数: $i"
done

for i in "$@"
do
        echo "参数: $i"
done

[root@docker data]# sh for2.sh 1 2 3 4 5
参数: 1
参数: 2
参数: 3
参数: 4
参数: 5
// 注意上面五条结果与下面五条结果分别使用$*、$@实现
参数: 1
参数: 2
参数: 3
参数: 4
参数: 5

参数: 1 2 3 4 5
// 此处为两这区别,$*将所有参数变为一个变量而$@仍为多个变量
参数: 1
参数: 2
参数: 3
参数: 4
参数: 5

(2)while

[root@docker data]# vim while.sh
[root@docker data]# cat while.sh 
#!/bin/bash

s=0
i=1
while [ $i -le 100 ]
do
        s=$[$s+$i]
        i=$[$i+1]
done

echo $s

[root@docker data]# sh while.sh 
5050

3. 括号问题

条件表达式 不能用 < >

while for 能用 < > 不能用 -gt

[] =》 条件判断

() => 数值运算

shell各种括号介绍https://blog.youkuaiyun.com/taiyang1987912/article/details/39551385?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2~default~CTRLIST~Rate-1.pc_relevant_default&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2~default~CTRLIST~Rate-1.pc_relevant_default&utm_relevant_index=1

七、函数

1. 系统函数

(1)basename获取文件的名称

[root@docker data]# basename /root/data/aa.sh 
aa.sh
[root@docker data]# basename /root/data/aa.sh .sh
aa

(2)dirname获取文件的路径

[root@docker data]# dirname /root/data/aa.sh 
/root/data

2. 自定义函数

(1)语法

[ function ] funName[()]
{
	content;
	[return int;]
}
funName
//  方括号部分都为可选部分

(2)实例

[root@docker data]# vim fun.sh 
[root@docker data]# cat fun.sh 
#!/bin/bash

function sum()
{
s=0
s=$[ $1 + $2 ]
echo "$s"
}
read s1;
read s2;

sum $s1 $s2
[root@docker data]# sh fun.sh
1
2
3

*六、Shell工具

1. cut

剪切文件每行的字符串,可以指定分隔符,分割后可以输出指定列,类似于split;

选项

-d

指定分隔符

cut -d "分隔符" file

-f

指定输出的对应列

cut -d "分隔符" -f 1 file

// 输出第一列

[root@docker data]# cat 1.log 
aa bb
aaa bbb
cc  bb
dd  dd
aa cc
// 1、以空格分隔1.log并输入第一列
[root@docker data]# cut -d " " -f 1 1.log 
aa
aaa
cc
dd
aa
// 2、输出aaa
[root@docker data]# cat 1.log | grep aaa
aaa bbb
[root@docker data]# cat 1.log | grep aaa | cut -d " " -f 1
aaa

2. sed

可以实现文本替换、文本插入、删除某行,但需要注意并非直接改变源文件,只是将想要的结果打印出来,当然,也可以存到文件中。

选项及命令

-e

用于衔接指令

a

在指定行后插入一行

d

删除包含某内容的行

s

查找某个词并替换

g

全局

// 文件1.log
[root@docker data]# cat 1.log 
aa bb
aaa bbb
cc  bb
dd  dd
aa cc

// 在包含aaa的一行下插入ee
[root@docker data]# sed "/aaa/a ee" 1.log 
aa bb
aaa bbb
ee
cc  bb
dd  dd
aa cc

// 在第二行下方插入一行ee
[root@docker data]# sed "2a ee" 1.log 
aa bb
aaa bbb
ee
cc  bb
dd  dd
aa cc

// 删除包含aaa的行
[root@docker data]# sed "/aaa/d" 1.log 
aa bb
cc  bb
dd  dd
aa cc

// 将文件中aa替换为ee
[root@docker data]# sed "s/aa/ee/" 1.log 
ee bb
eea bbb
cc  bb
dd  dd
ee cc

// 先将文件中aa替换为ee,再删除eea 此处时-e的使用
[root@docker data]# sed -e "s/aa/ee/" -e  "/eea/d" 1.log 
ee bb
cc  bb
dd  dd
ee cc

3. awk

切割文件,如果匹配到指定格式的内容指定设定的动作,默认空格分隔。

选项

-F

指定分隔符

-v

赋值一个用户定义变量

内置变量

FILENAME

文件名

NR

已读的行数

NF

切割后列的个数

[root@docker data]# vim 2.log
[root@docker data]# cat 2.log 
aa:bb
aaa: :bbb
cc:bb
dd:a:dd

aa:cc:ee

// 输出以aa开头的行的第二列
[root@docker data]# awk -F : '/^aa/{print $2}' 2.log 
bb
 
cc

// 在整个输出的前后加内容
[root@docker data]# awk -F : 'BEGIN{print "begin"} /^aa/{print $2} END{print "end"}' 2.log 
begin
bb
 
cc
end

// 自定义变量
[root@docker data]# awk -F : -v i=1 '/^aa/{print $2""i}' 2.log 
bb1
 1
cc1

// 输出文件名、当前行、所有行数
[root@docker data]# awk -F : -v i=1 '{print "fileName:"FILENAME "nowLine:"NR "colNum:" NF}' 2.log 
fileName:2.lognowLine:1colNum:2
fileName:2.lognowLine:2colNum:3
fileName:2.lognowLine:3colNum:2
fileName:2.lognowLine:4colNum:3
fileName:2.lognowLine:5colNum:0
fileName:2.lognowLine:6colNum:3


[root@docker data]# cat 2.log 
aa:bb
aaa: :bbb
cc:bb
dd:a:dd

aa:cc:ee

// 查找第几行为空行 其中/^$/为正则
[root@docker data]# awk '/^$/{print NR}' 2.log 
5

4. sort

对文件内容排序

选项

-n

数值大小排序

-r

倒序

-t

设置分隔字符

-k

指定排序的列

[root@docker data]# cat 3.log 
1:2:33
10:22:1
33:21:34
14:33:11
22:12:34
// 以:为分隔符 以数值倒序对第2列排序
[root@docker data]# sort -t : -nrk 2  3.log 
14:33:11
10:22:1
33:21:34
22:12:34
1:2:33

shell脚本成分 开头和注释: shell脚本的开头,用来解释shell程序,包括:#!/bin/bash、#!/bin/csh、#!/bin/tcsh、#!/bin/pdksh,一般用#!/bin/bash。。 shell脚本中的注释,以#开头的句子表示注释。 变量: 变量的赋值和引用 在shell编程中变量没有类型,简称弱类型编程语言,不需要声明,在引用这个变量时会创建它(在变量名前加$符号引用变量的值)。在定义变量时,若String中包含空格、制表符、换行符,需用单(双)引号,双引号内允许变量替换,而单引号内就不可以。 shell变量的作用域 可以用export内置命令将局部变量设置为全局变量。 位置变量 用于向shell脚本传递信息。参数相关数目传入脚本,此数目任意多,但只有前9个可以被访问,使用shift命令可以改变限制。其中,$0:脚本名字。 特定变量参数 $#:传递到脚本的参数个数;$*:以一个单字符串显示所有项脚本传递的参数。与位置变量不通,此选项参数可超过9个;$$:脚本运行的当前进程ID号;&!:后台运行的最后一个进程的进程ID号;$@:与$#相同,但是使用时加引号,并在引号中返回每个参数;$-:显示shell使用的当前选项,与set命令功能相同;$?:显示最后命令的退出状态(0表示没有错误,其他任何值表明有错误。)。 变量的规则 1.变量与变量内容以一个等号『=』来连结,如下所示『myname=VBird』 2.等号两边不能直接接空格符,如下所示为错误:『myname = VBird』或『myname=VBird Tsai』 3.变量名称只能是英文字母与数字,但是开头字符不能是数字,如下为错误:『2myname=VBird』 "4.变量内容若有空格符可使用双引号『""』或单引号『'』将变量内容结合起来,但 双引号内的特殊字符如 $ 等,可以保有原本的特性,如下所示:『var=""lang is $LANG""』则『echo $var』可得『lang is en_US』 单引号内的特殊字符则仅为一般字符 (纯文本),如下所示:『var='lang is $LANG'』则『echo $var』可得『lang is $LANG』" 5.可用跳脱字符『 \ 』将特殊符号(如 [Enter], $, \, 空格符, '等)变成一般字符; "6.在一串命令中,还需要藉由其他的命令提供的信息,可以使用单引号『`命令`』或 『$(命令)』 特别注意:那个 ` 是键盘上方的数字键 1 左边那个按键,而不是单引号! 例如想要取得核心版本的配置:『version=$(uname -r)』再『echo $version』可得『2.6.18-128.el5』" "7.若该变量为扩增变量内容时,则可用 ""$变量名称"" 或 ${变量} 累加内容,如下所示: 『PATH=""$PATH"":/home/bin』" 8.若该变量需要在其他子程序运行,则需要以 export 来使变量变成环境变量:『export PATH』 9.通常大写字符为系统默认变量,自行配置变量可以使用小写字符,方便判断 (纯粹依照使用者兴趣与嗜好) ; 10.取消变量的方法为使用 unset :『unset 变量名称』例如取消 myname 的配置:『unset myname』
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

isMr_Sun

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值