什么是Shell,初识Shell脚本Shell编程,shell介绍,Linux
  AWkq7aIjuRwO 2023年11月02日 52 0

脚本

脚本就是批处理

平常一个命令不能完成的任务,写到一个文件当中,有多个命令按照一定的逻辑来进行编写

编写完后去执行这个文件,随后他就会按照流程多个命令,多个语句,达到批处理的一个任务

shell 

什么是Shell,初识Shell脚本Shell编程,shell介绍,Linux_vim


系统分成了三层

第一层是kernel(内核)内核是操作系统的核心,主要负责管理硬件,电脑cpu是什么样的、内存多大、硬盘多大、显卡是啥样的,这些都是由内核去管理,他管理计算机所有的硬件,包括直接连的和间接连的,直接连的比如:内存、CPU。间接连的比如:打印机。同时他还要负责驱动硬件干活,比如你要打印照片,内核会告诉打印机:去把某照片打印,打印机就去打印了。

内核是负责管理硬件和驱动硬件干活

第二层:shell:命令解释器 用户和内核语言不同,内核识别的是二进制,1和0 内核只认识1和0。shell作为翻译官,用户下达命令,shell去解释翻译给内核,内核再去调用硬件去干活。

shell:介于系统内核与用户之间,负责解释命令行

第三层:用户user:下指令的,内核为啥要给你打照片?是因为用户告诉内核去把我的照片打一下,内核才去找打印机去打照片,用户是下指令的,下指令给内核,内核去干,内核让设备去干,那么shell的作用是啥


什么是Shell,初识Shell脚本Shell编程,shell介绍,Linux_bc_02

shell脚本

是按照shell语法的规则去编写的脚本称为shell脚本(里面写的大部分都是shell命令)


1什么是Shell

Shell是命令解释器  解释用户输入的命令

Shell的分类:

面试题:Linux中默认的Shell是什么?

bash

两个概念

交互式shell:用户输入命令 bash解释用户输入的内容 执行完后 bash退出 称为交互式  和人交互的过程
非交互式shell 不和用户交互 执行脚本中的内容 执行到结尾 bash结束 称为非交互式shell

2.什么是shell脚本

把命令写入到文本中,执行这个文件称为shell脚本,包含了变量 判断 循环 数组函数 比较表达式等等

3.语言种类

c c++ java python html ruby go php ....shell

编译型语言:

比如c语言,一次性编译终身执行,就和我开发了c语言中编译了二进制,计算机能够认识的语言,认识了第二次直接执行它,计算机还认识,就是一次编译,后面都可以运行

解释型语言

每次我执行都需要解释一遍
shell和python的区别
shell可以处理系统底层的功能 系统中的管理程序 启动 停止 运行 数据统计 数据分析 安装服务 配置 服务 管理服务
python 页面 cmdb自动化运维平台 业务程序 实现某个功能 
python是自动化运维必须的!

3.创建shell脚本的规范

1.存放统一目录  方便做自动化管理 先要有规范 /server/scripts
2.脚本结尾必须以.sh结尾
3.脚本开头以#!/bin/bash 开头或者 #!/bin/sh
4.脚本中要有注释
date
author
功能:
5.注释尽量不用中文  可以使用中文
6.脚本中的符号一次性书写完成  必须英文符号
如'' "" {} ()


查看一下当前系统所支持的shell

总共就两个bash和tcsh

什么是Shell,初识Shell脚本Shell编程,shell介绍,Linux_vim_03

下图这几个都指向的bash     l开头的是符号链接

nologin  是不能登录的意思

什么是Shell,初识Shell脚本Shell编程,shell介绍,Linux_bc_04

什么是Shell,初识Shell脚本Shell编程,shell介绍,Linux_bash_05

下图两个都指向的tcsh  l开头的是符号链接

什么是Shell,初识Shell脚本Shell编程,shell介绍,Linux_vim_06


什么是Shell,初识Shell脚本Shell编程,shell介绍,Linux_bash_07

用户一登录就会得到一个shell,并且以下图提示符的形式让用户命令输出执行

什么是Shell,初识Shell脚本Shell编程,shell介绍,Linux_bc_08

是因为执行了bash这个命令后得到的这个环境

查看一下当前用户root 使用的shell

grep ^root /etc/passwd

下图写着/bin/bash

用户一登录就会执行这个命令他就会最后得到一个提示符相当于已经打开bash这个shell环境了,然后敲命令,他就会解释给内核,内核去驱动硬件

什么是Shell,初识Shell脚本Shell编程,shell介绍,Linux_bc_09

给用户更改shell

usermod -s /bin/csh user1

更改user1 用户的登录shell 为csh


编写第一个sehll脚本

格式 用vim编写  一般以.sh作为后缀(目的为了让其他人知道这是一个shell脚本)

vim test.sh

第一行脚本声明

#!/bin/bash

第二行注释信息

# 写上注释比如:这个脚本是干什么的啥啥啥

接下里是可执行语句

命令

保存退出

接下来 赋予可执行权限 使脚本具有可执行属性

chmod +x test.sh

然后执行脚本文件

方法一:脚本文件路径 直接写路径 绝地路径 或相对路径 需要有执行脚本权限

./test.sh       #绝对路径/test.sh (需要有x权限)

方法二:sh  脚本文件路径   

sh ./test.sh  #或者sh 绝对路径/test.sh  或者sh test.sh  (不需要有x权限)

方法三:source  脚本文件路径

source ./test.sh   或者. ./test.sh 或. 绝对路径/test.sh  或. test.sh(不需要有x权限)


./test.sh和sh test.sh 都是去子shell去执行的,执行完毕后关闭子shell

结果反馈给父shell的屏幕上 不会影响当前shell

. test.sh 是在当前shell下执行 并反馈给当前shell  会影响当前shell

切换子shell  直接敲bash  然后就去bash了  pstree 查看

一个进程相当于一个加工厂一样他有:

进料口(标准输入0(键盘))

出料口(标准输出1(显示器))

废料口(标准错误输出2(显示器))

什么是Shell,初识Shell脚本Shell编程,shell介绍,Linux_bash_10

列如执行一个命令

cat

然后输入 默认从键盘输入 他再从屏幕输出

cat前门进后门出  输入是键盘 输出是屏幕

什么是Shell,初识Shell脚本Shell编程,shell介绍,Linux_vim_11


如果我不想在屏幕上显示了

cat 1> test1
ctrl +d 提交

什么是Shell,初识Shell脚本Shell编程,shell介绍,Linux_bc_12

more test1  查看文件内容

什么是Shell,初识Shell脚本Shell编程,shell介绍,Linux_vim_13

标准输出1 对应位置是显示器 如果要改变位置就写1> 跟上文件名 这样就不在屏幕上显示了 (1> 只能保存正确输出信息)1>>追加

1> 代表的是标准输出重定向  做的比较多 一般>就代表1> 了 不用加1了

2> 


比如我写错了他就会有错误提示

ls -jkl

什么是Shell,初识Shell脚本Shell编程,shell介绍,Linux_bash_14


如果错误提示我不想在屏幕上显示了,想把他保存到一个 文件当中去

ls -jkl 2> test2

什么是Shell,初识Shell脚本Shell编程,shell介绍,Linux_bash_15

标准错误输出2 对应位置显示器 如果改变位置就写2> 跟上文件名 这样就不在屏幕上显示了 (2> 只能保存错误输出信息)2>>追加


还有种写法 不管对错 都保存到一个文件中

&> 混合输出重定向

什么是Shell,初识Shell脚本Shell编程,shell介绍,Linux_bc_16

>覆盖式    清空原来文件内容 然后写新的

>>追加式  原来的文件内容不会被破坏,在后面追加上

类型

设备文件

文件描述编号

默认设备

标准输入

/dev/stdin  

0

键盘

标准输出

/dev/stdout  

1

显示器

标准错误输出

/dev/stderr

2

显示器

cat < test1

从test1中替代标准输入,交给cat是执行   标准输入是键盘替代键盘了

什么是Shell,初识Shell脚本Shell编程,shell介绍,Linux_vim_17

类型

操作符

用途

重定向输入

<

从指定的文件读取数据,而不是从键盘输入



重定向输出

>

将输出结果保存到指定的文件(覆盖原有内容)


>>

将输出结果追加到指定的文件



标准错误输出

2>

将错误信息保存到指定的文件(覆盖原有内容)


2>>

将错误信息追加到指定的文件中


混合输出

&>

将标准输出、标准错误的内容保存到同一个文件中




管道操作符号“|”

将左侧的命令输出结果,作为右侧命令的处理对象

管道的前后都是对应的命令,每个命令对应的是个进程,如果一个命令不能完成我们需要的结果,就有可能把一个命令正常输出结果交给另外一个命令作为标准输入,然后再加下来处由图中2 的标准进程输出来 最终输出的内容是第二个进程的

还有可能还有其他进程,依次下去

什么是Shell,初识Shell脚本Shell编程,shell介绍,Linux_bc_18

比如

ls -l /etc  想要分页显示

ls -l /etc | more

awk

grep ^root /etc/passwd

什么是Shell,初识Shell脚本Shell编程,shell介绍,Linux_bash_19

比如我只想看第一段和最后一段 也就是root 和他的shell

grep ^root /etc/passwd | awk -F: '{print $1,$7}'

什么是Shell,初识Shell脚本Shell编程,shell介绍,Linux_vim_20

awk是按列或者按字段进行处理的一个工具,只要在一行中能够明确他的分隔符是谁他就按着他的分隔符去找到相应的列,然后进行处理

-F: 就是awk进行列处理的时候他的分隔符是: 如果列与列之间用空格分割这个就可以不写 默认分隔符就是空格

print 是打印的意思 就是在屏幕上输出的意思

$1代表第一列$7 代表第七列 中间用,隔开


shell变量的作用、类型

变量的作用

什么叫变量:定义变量:就是在内存中指定一个空间并且赋值

比如我定义一个变量ABC=12345678910111213141516…

变量的优点:方便来引用,如果频繁用这串数字,那么用的时候就可以$ABC

$ABC代表引用变量

变量的作用:增加脚本灵活性


变量的类型

1自定义变量:由用户自己定义、修改和使用 如ABC=123 用户自己设置的

2环境变量:由系统维护,用于设置工作环境   比如PATH 系统自己设置好了 也可以给他改变值

3预定义变量:Bash中内置的一类变量,不能直接修改    特殊的保留变量,这个名字早就固定好了,有特殊的含义,当我们执行脚本的时候这个变量就自动赋值了

位置变量:通过命令行给脚本程序传递参数,是一种预定义变量

定义一个新的变量

格式:变量名=变量值   列如ABC=123     第一个数不能是数字 可以是下划线

变量名以字母或下划线开头,区分大小写,建议全大写

查看变量的值

格式:echo  $变量名   echo $ABC


自定义变量#####

变量赋值及引用时使用符号
双引号:允许通过$符号引用其他变量值
单引号:禁止引用其他变量值,$视为普通字符
反撇号:命令替换,提取命令执行后的输出结果
$():命令替换,命令嵌套是可替代反撇号
${}:引用变量,用于区分变量名与紧跟其后的字符串



双引号:允许通过$符号引用其他变量值

列如abc=123 456   空格属于特殊符号 但是系统认为前面是一个命令后面是一个命令

什么是Shell,初识Shell脚本Shell编程,shell介绍,Linux_vim_21


像这种情况需要用引号引起来让系统识别abc=“123 456”

什么是Shell,初识Shell脚本Shell编程,shell介绍,Linux_vim_22


单引号:禁止引用其他变量值,$视为普通字符

什么是Shell,初识Shell脚本Shell编程,shell介绍,Linux_bc_23

单引号也可以用来引用字符串他与双引号不同的是
双引号把$识别为变量引用
而单引号仅仅把$识别为普通字符


什么是Shell,初识Shell脚本Shell编程,shell介绍,Linux_bash_24

什么是Shell,初识Shell脚本Shell编程,shell介绍,Linux_bash_25

反撇号:命令替换,提取命令执行后的输出结果
我想看下vim的命令的目录 which vim

什么是Shell,初识Shell脚本Shell编程,shell介绍,Linux_vim_26

用变量查看:如果说我想把一个命令的结果放到什么位置这叫命令替换
可以用反撇号``
vim_weizhi=which vim

什么是Shell,初识Shell脚本Shell编程,shell介绍,Linux_bc_27


什么是Shell,初识Shell脚本Shell编程,shell介绍,Linux_vim_28

把上面的查询过程写到一块交给一个变量
vim_bao=`rpm -qf `which vim``
这样是不成的因为反撇号是朝一个方向的,他无法正确识别。不知道那个和那个是一对所以需要$()
$():命令替换,命令嵌套是可替代反撇号注意!()前面要加$
vim_bao=(which vim))

什么是Shell,初识Shell脚本Shell编程,shell介绍,Linux_bash_29


反撇号和$小括号都是进行命令替换的但是$小括号可以进行命令嵌套

#另外两种写法:只要不冲突就行
vim_bao=$(rpm -qf `which vim`)
vim_bao=rpm -qf $(which vim)

什么是Shell,初识Shell脚本Shell编程,shell介绍,Linux_bc_30

什么是Shell,初识Shell脚本Shell编程,shell介绍,Linux_bc_31

${}:引用变量,用于区分变量名与紧跟其后的字符串
abc=123
echo $abc
bcd=“$abc456”
echo $bcd   这个时候是显示不出来的$abc和456连在一块认成一个变量了
变量名和紧跟其后的字符串混淆了,
这个时候就需要加上${}了
bcd=$”{abc}456”

什么是Shell,初识Shell脚本Shell编程,shell介绍,Linux_bc_32

#有些人不管有没有东西只要是变量 都用这种语法表示
echo ${bcd}

什么是Shell,初识Shell脚本Shell编程,shell介绍,Linux_bash_33


交互赋值:一问一答

比如

read abc 回车 就会等待我们给abc赋值

我输入99999

什么是Shell,初识Shell脚本Shell编程,shell介绍,Linux_bc_34


read=读  从哪读 从键盘读

从键盘读东西出来交给abc

完整语法

read -p “please input value:” abc

什么是Shell,初识Shell脚本Shell编程,shell介绍,Linux_vim_35

自定义变量

设置变量的作用范围

格式1:export   变量名 ...

格式2: export  变量名=变量值  ...

——两种格式可以混合使用

全局变量是变量在当前shell和子shell都可以使用,父shell不可

局部变量 仅在本shell当中生效的  父shell 和子shell 都不生效

如何创建全局变量

export abc=123   在给abc赋值的时候前面加上export
如何给局部变量设置为全局变量
abc=123
export abc   这是给局部变量设置为全局变量


整数变量的运算

格式: 计算的时候运算符前后有空格 也就是加减乘除和数字前后都要有空格

expr 2 \* 3 + 1 – 4 / 2

什么是Shell,初识Shell脚本Shell编程,shell介绍,Linux_vim_36


什么是Shell,初识Shell脚本Shell编程,shell介绍,Linux_bash_37

常用运算符
加法运算:+
减法运算: -
乘法运算: \*
除法运算: /
求模(取余)运算: %

取余就是俩数相除得的余数

什么是Shell,初识Shell脚本Shell编程,shell介绍,Linux_vim_38

环境变量 维护当前系统环境的变量

这些变量往往都是系统设置好的,有可能要读,也有可能要去修改

这些变量要定义在

/etc/profile (全局的对于所有用户都生效)
~/.bash_profile (只对当前用户生效 ~代表当前宿主目录)

常见的环境变量:环境变量默认都是大写的

PWD、PATH

USER 、SHELL、HOME

查看当前用户

echo $USER

什么是Shell,初识Shell脚本Shell编程,shell介绍,Linux_vim_39

查看当前所在的目录

echo $PWD

什么是Shell,初识Shell脚本Shell编程,shell介绍,Linux_bash_40

查看命令搜索路径

echo $PATH

什么是Shell,初识Shell脚本Shell编程,shell介绍,Linux_vim_41

查看当前shell

什么是Shell,初识Shell脚本Shell编程,shell介绍,Linux_bash_42

位置变量


预定义变量

$#:命令行中位置变量的个数

$*:所有位置变量的内容

$?:上一条命令执行后返回的状态,当返回状态值为0时表示执行正常,非0值表示执行异常或出错

$0:当前执行的进程/程序名


写个脚本

vim test1.sh

什么是Shell,初识Shell脚本Shell编程,shell介绍,Linux_vim_43

chmod +x test1.sh
./test1.sh

什么是Shell,初识Shell脚本Shell编程,shell介绍,Linux_bc_44

第一次执行的时候后面没有跟任何东西 得到的结果是

什么是Shell,初识Shell脚本Shell编程,shell介绍,Linux_vim_45

第二次执行的时候 后面跟了a b c d e f  参数用空格隔开

什么是Shell,初识Shell脚本Shell编程,shell介绍,Linux_bash_46

echo $0  第一行是输出了$0的结果a给$0赋值等于 ./test1.sh  $0指的脚本名
echo $1  第二行是输出的$1的结果 b给$1赋值 结果 a $1是脚本执行后 后面跟的第一个参数
echo $2  第二行是输出的$2的结果 b 给$2赋值
c 给$3赋值 因为里面没有$3 所以就不管了
echo $4  第二行是输出的$4的结果 d给$4赋值
从$1-$9 他是依靠在执行脚本是后面跟的参数的位置进行赋值 第一个参数给$1赋值第二个参数给$2赋值 一直到$9  没有$10和$11
echo #  最后看到的是参数的个数 一共6个参数  所以显示6
echo $* 是参数的内容 内容是a b c d e f

什么是Shell,初识Shell脚本Shell编程,shell介绍,Linux_vim_47

执行脚本的三种方式

第一种: sh test.sh   #不需要执行权限   使用子shell执行
第二种: /server/scripts/test.sh  或者 ./test.sh  #需要执行权限
第三种: source test.sh  #父shell执行  登录的shell 第一个窗口就是父shell

for在命令行中使用

[root@scripts ~]# for i in 1 2 3; do echo $i;done 
1
2
3

shell核心位置环境变量

$0      #表示脚本的名称 全路径执行 显示全路径的脚本名称 
$n      #表示脚本的底n个参数 n为数字 0已被脚本名占用 从1 开始 从$9后需要加{}引起来作为一个整体 ${}
$#      #表示传参的个数 控制传参的个数
$*      #表示传参的所有参数 不加双引号和$@相同 加上双引号 表示为一个参数 在脚本中相同 循环体中不同
$@      #表示传参的所有参数 不加双引号和$*相同 加上双引号 表示为正常的传参
$?      #表示上一条命令执行结果 0为成功 非0为失败 返回值0-255 可以自定义返回值
$$      #表示当前脚本的pid

只要脚本中出现一次的,我们都使用变量

变量的子串

[root@scripts scripts]# name='i am qichen'
[root@scripts scripts]# echo $name
i am qichen
[root@scripts scripts]# #我要单独取出am来
[root@scripts scripts]# echo ${name:2:2}
am
[root@scripts scripts]# #取出a来
[root@scripts scripts]# echo ${name:2:1}
a
[root@scripts scripts]# #取出c来
[root@scripts scripts]# echo ${name:7:1}
c

统计变量字串的长度

awk的执行过程是一行一行执行

#第一种方式
[root@scripts scripts]# echo $name
i am qichen
[root@scripts scripts]# echo $name | wc -L
11
wc -L       #统计文件中最长的行的长度,如果为一行那就统计一行的
#第二种方式
[root@scripts scripts]# echo $name
i am qichen
[root@scripts scripts]#  echo ${#name}
11
#第三种方式
[root@scripts scripts]# expr length "$name"
11
#length     #长度
#第四种方式
[root@scripts scripts]# echo $name | awk '{print length}'
11

统计出变量中长度小于3的值

[root@scripts scripts]# echo $name
I an fengqichen teacher I am 18
#要求算出长度小于3的值
#方法一
#写脚本bash
[root@scripts scripts]# cat for.sh 
#!/bin/bash
name='I am fengqichen teacher I am 18'
for i in $name
do
b=$(echo ${#i})
if [ $b -lt 3 ]
then
    echo "${i}"
fi
done
[root@scripts scripts]# sh for.sh 
I
am
I
am
18
#还一个更简洁的脚本
[root@scripts scripts]# cat for.sh 
#!/bin/bash
name='I am fengqichen teacher I am 18'
for i in $name
do
[ ${#i} -lt 3 ] && echo "${i}"
done
[root@scripts scripts]# sh for.sh 
I
am
I
am
18
#另一种方法
[root@scripts scripts]# echo $name
I an fengqichen teacher I am 18
[root@scripts scripts]# echo $name | xargs -n1
I
an
fengqichen
teacher
I
am
18
[root@scripts scripts]# echo $name | xargs -n1 | awk '{print length}'
1
2
10
7
1
2
2
[root@scripts scripts]# echo $name | xargs -n1 | awk '{ if (length<3) print}'
I
an
I
am
18
#if判断如果length得到的长度小于3那么就print显示出来
#第三种方法
#$NF是取出最后一列的内容,NF是取出最后一列的列号,比如
[root@scripts scripts]# cat 1.txt 
abc ddd ff  gg hh   tt
dawd eaf wada esg th
awd 23 436d ytnyt esf
[root@scripts scripts]# cat 1.txt | awk '{print $NF}'
tt
th
esf
[root@scripts scripts]# cat 1.txt | awk '{print NF}'
6
5
5

[root@scripts scripts]# echo $name | awk '{for(i=1;i<=NF;i++)if(length($i)<3)print $i}'
I
an
I
am
18

#解释:
[root@scripts scripts]# echo $name
I an fengqichen teacher I am 18
#首先看
echo $name | awk '{for (i=1;i<=NF;i++)}'
#i=1 i<=NF(NF是最后一列的列号在这里是7) i++
echo $name | awk '{for(i=1;i<=NF;i++) if(length($i)<3)print $i}'
#if判断(length ($i)<3) 如果小于那么就输出print $i}
第一次i=1   然后查看第一列  统计第一列的长度 length 1 真实的第一列是I  他的长度是1  1<3 那么输出
第二次i=2   然后查看第二列  统计第二列的长度 length 2 真实的第二列是 an  他的长度是2 2<3 那么输出
第三次i=3   然后查看第三列  统计第三列的长度 length 3 真实的第三列是 fengqichen 他的长度是10 10不<3 那么不输出
第四次i=4   然后查看第四列  统计第四列的长度 length 4 真实的第四列是 teacher 他的长度是7 7不<3 那么不输出
第五次i=5   然后查看第五列  统计第五列的长度 length 5 真实的第五列是 I 他的长度是1 1<3 那么输出
以此类推 直到i=7 结束后 中止循环


【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
  bYdMetjCLs2g   2023年11月28日   21   0   0 bash
  YKMEHzdP8aoh   2023年11月30日   32   0   0 vimUDP
  wwLZeziuqjLR   2023年12月08日   99   0   0 Dockercentosbash
  xIUntf9oR6GI   2023年11月28日   28   0   0 sedvim基础命令
  mjtHZIki74si   2023年12月06日   30   0   0 ubuntubash
  hHWnOnebRjW2   2023年11月27日   23   0   0 PostgreSQLsqlbash
  48fXx4UfWSFg   2023年12月06日   54   0   0 bcIPbundle
  vxoexqgjyiCS   2023年11月25日   19   0   0 linuxbash数组
AWkq7aIjuRwO