当前位置: 首页 > news >正文

Linux操作系统shell脚本

目录

一、Shell脚本语言的基本结构

1、Shell脚本的用途:

2、 Shell脚本基本结构:

3、 创建Shell脚本过程

4、 脚本注释规范

5、第一个脚本

6、 执行脚本

7、脚本错误

二、Shell脚本语言的变量用法详解

1、变量

2、 变量类型

3、 Shell中变量命名法则

4、 变量定义和引用

5、 环境变量

6、只读变量

7、位置变量

8、 退出状态码变量

三、 Shell字符串详解

1、Shell字符串拼接

2、Shell字符串截取

四、Shell脚本语言的运算

4.1 算数运算

4.2 Bash中的算术运算

4.2 实现算术运算

4.3 增强型赋值:

4.2 逻辑运算


一、Shell脚本语言的基本结构

1、Shell脚本的用途:

自动化常用命令

执行系统管理和故障排除

创建简单的应用程序

处理文本或文件

2、 Shell脚本基本结构:

Shell脚本编程:是基于过程式,解释执行的语言

编程语言的基本结构:

  • 各种系统命令的组合

  • 数据存储:变量,数组

  • 表达式:a+b

  • 控制语句:if、case、for、while

shell脚本:包含一些命令或声明,并符合一定格式的文本文件

格式要求:首行执行shebang机制

#声明后续语句是通过那种语言写的
#!/bin/bash
#!/usr/bin/python
#!/usr/bin/perl

3、 创建Shell脚本过程

使用vim创建文本文件,第一行必须包括shell声明序列:
#!/bin/bash
[root@localhost log]# echo  $SHELL
/bin/bash加执行权限,给予执行权限,在命令行上指定脚本的绝对或相对路径

加执行权限,给予执行权限,在命令行上指定脚本的绝对或相对路径

[root@localhost ~]# vim scripts1.sh
[root@localhost ~]# chmod +x script1.sh

运行脚本,直接运行解释器,将脚本作为解释器程序的参数运行

[root@localhost ~]# /root/shellScript/hello.sh 

4、 脚本注释规范

  • 第一行一般为调用使用的语言

  • 程序名,避免更改文件名为无法找到正确的文件

  • 版本号

  • 更改后的时间

  • 作者相关信息

  • 该程序的作用,及注意事项

  • 最后是各版本的更新简要说明

#!/bin/bash
3auth:Mr  yuetangbinghua
#Use:列出系统中的普通文件
Date:2026年——06——04
#version: 1.0
cd /home
。/script1.sh
find /home -type f

5、第一个脚本

[root@localhost ~]# cat shell/hostname.sh 
#!/bin/bash
echo "My hostname is `hostname`"
echo "Time is `date +'%F %T'`"
[root@localhost ~]# chmod +x shell/hostname.sh
[root@localhost ~]# shell/hostname.sh

6、 执行脚本

1、增加执行权限,执行脚本时会创建一个子shell,不影响现有的shell环境

chmod +x sh
./sh
/root/shellScript/sh

2、使用 . 或者source,执行脚本时不会创建一个子shell,会影响现有的shell环境

source sh
. sh

不要使用(点)方式执行脚本

7、脚本错误

  • 语法错误,会导致后续的命令不继续执行,可以用bash -n shellname检查错误

  • 命令错误,后续的命令还会继续,可以使用bash -x shellname检查

  • 逻辑错误,只能使用bash -x进行观察

二、Shell脚本语言的变量用法详解

1、变量

变量表示命名的内存空间,将数据放在内存空间中,通过变量名引用,获取数据

2、 变量类型

变量类型:

内置变量:如PS1,PATH,UID,HOSTNAME,HISTSIZE

用户自定义变量

预定义变量

位置变量

不同的变量存放的数据不同,决定了以下:

  1. 数据存储方式

  2. 参与的计算

  3. 表示的数据范围

变量数据类型:

  • 字符串

  • 数值:整型,浮点型(小数)、bash不支持浮点数

3、 Shell中变量命名法则

  • 不能使用程序中的保留字,如:if,for

  • 只能使用数字,字母及下划线,且不能以数字开头

  • 见名思意,用英文名字,并体现真正含义

  • 统一命名规则:驼峰命名法

  • 全局变量名大写

  • 局部变量小写

  • 函数名小写

    [root@localhost ~]# a=1
    [root@localhost ~]# echo  $7[root@localhost ~]# ls /etc/  /home/
    

  • [root@localhost ~]# a=2
    [root@localhost ~]# n1=1
    [root@localhost ~]# userName=list
    [root@localhost ~]# env
    [root@localhost ~]# export  a-1
    bash: export: `a-1': 不是有效的标识符
    [root@localhost ~]# bash
    [root@localhost ~]# echo  $a[root@localhost ~]# exit
    exit

4、 变量定义和引用

变量的生效范围(变量作用域)

  • 普通变量:生效范围为当前shell进程;对当前shell之外的其他shell进程,包括当前shell的子shell进程均无效

  • 环境变量:生效范围为当前shell进程及其子进程

  • 本地变量:生效范围为当前shell进程中某代码片段,通常指函数

[root@localhost ~]# rs2=./*
[root@localhost ~]# echo  $rs2
./公共 ./模板 ./视频 ./图片 ./文档 ./下载 ./音乐 ./桌面 ./anaconda-ks.cfg ./hexiuxiu.md ./hutao ./ifcfg-ens160 ./initial-setup-ks.cfg ./liyue ./scripts1.sh ./wangziyi ./yunji

注意:变量赋值是临时生效,当退出终端后,变量会自动删除,无法持久保存。

变量引用:

$name
${name}

弱引用和强引用:

  • “$name”:弱引用,其中的变量引用会被替换成为变量值

  • ‘$name’:强引用,其中的变量引用不会被替换成变量值,而保持原字符串

删除变量

[root@localhost ~]# set  |  wc  -l
3106
[root@localhost ~]# unset  str1
[root@localhost ~]# echo  $str1[root@localhost ~]# str1=wang
[root@localhost ~]# 
[root@localhost ~]# 
[root@localhost ~]# 
[root@localhost ~]# echo  $str2
$str1
[root@localhost ~]# echo  $str3
yueliang
[root@localhost ~]# str4=$str1444
[root@localhost ~]# echo  $str4[root@localhost ~]# str4=${str1}444

利用变量实现动态命令

[root@localhost ~]# CMD=hostname
[root@localhost ~]# $CMD
localhost.localdomain
[root@localhost ~]#

5、 环境变量

环境变量:

  • 可以使子进程(包括孙子进程)继承父进程的变量,但是无法让父进程使用子进程的变量。

  • 一旦子进程修改了从父进程继承的变量,将会传递新的值给孙子进程

  • 一般只在配置文件中使用,在脚本中较少使用

[root@localhost ~]# vim shell/father.sh 
#!/bin/bash
NAME=father
echo "father.sh:NAME=$NAME"
echo "fatther is PID=$BASHPID"
shell/son.sh[root@localhost ~]#vim shell/son.sh
#!/bin/bash
echo "son.sh:NAME=$NAME"
NAME=son
echo "son.sh:NAME=$NAME"
echo "son.sh PID is $BASHPID"
echo "son.sh father pid is $PPID"
sleep 100[root@localhost ~]#chmod -R +x shell/*[root@localhost ~]# ./shell/father.sh 
father.sh:NAME=father
fatther is PID=12053
son.sh:NAME=
son.sh:NAME=son
son.sh PID is 12054
son.sh father pid is 12053

6、只读变量

只读变量:只能声明定义,但后续不能修改和删除

7、位置变量

位置变量:在Bash Shell中内置的变量,在脚本代码中调用命令行传递给脚本的参数

[root@localhost ~]# vim shell/ARG.sh
#!/bin/bash
echo "1st arg is $1"
echo "2st arg is $2"
echo "3st arg is $3"
echo "4st arg is $4"
echo "The number of are is $#"
echo "All args are $*"
echo "All args are $@"
echo "The scriptname is `basename $0`"
[root@localhost ~]# chmod +x shell/ARG.sh 
[root@localhost ~]# shell/ARG.sh {1..10}
1st arg is 1
2st arg is 2
3st arg is 3
4st arg is 4
The number of are is 10
All args are 1 2 3 4 5 6 7 8 9 10
All args are 1 2 3 4 5 6 7 8 9 10
The scriptname is ARG.sh

8、 退出状态码变量

进程执行后,将使用变量 ? 保存状态码的相关数字,不同的值反应成功与失败, ?保存状态码的相关数字,不同的值反应成功与失败, ?保存状态码的相关数字,不同的值反应成功与失败,的取值范围为[0,255]

[root@localhost ~]# ping -c 2 www.baidu.com > /dev/null 
[root@localhost ~]# echo $?
0
[root@localhost ~]# cmd
-bash: cmd: 未找到命令
[root@localhost ~]# echo $?
127
[root@localhost ~]# 

exit表示退出当前 Shell 进程,我们必须在新进程中运行 test.sh,否则当前 Shell 会话(终端窗口)会被关闭,我们就无法取得它的退出状态了

三、 Shell字符串详解

字符串(String)就是一系列字符的组合。字符串是Shell编程中最常用的数据类型之一

字符串可以由单引号''包围,也可以由""包围,也可以不用引号,三种方式的区别

1由单引号' '包围的字符串
2由双引号" "包围的字符串
3不被引号包围的字符串#!/bin/bash
n=74
str1=c.biancheng.net$n 
str2="shell \"Script\" $n"
str3='C语言中文网 $n'
echo $str1
echo $str2
echo $str3# 运行结果
c.biancheng.net74
shell "Script" 74
C语言中文网 $n

1、Shell字符串拼接

#!/bin/bash
name="shell"
url="http://c.biancheng.net/shell/"
str1=$name$url 
str1=$name":"$url
str2="$name $url"
str3="$name:$url" 
str4="${name}Script:${url}Index.html" 

2、Shell字符串截取

Shell截取字符串通常有两种方式,从指定位置开始截取和从指定字符(子字符串)开始截取

从指定位置开始截取

1.从字符串左边开始计数

url="c.biancheng.net"
echo ${url:2:9}>结果为:bianchengurl="c.biancheng.net"
echo ${url:2} #省略length,截取到字符串末尾>结果为:biancheng.net

2.从右边开始计数

如果想从字符串的右边开始计数,那么截取字符串的具体格式如下

url="c.biancheng.net"
echo ${url:0-13:9}>结果为:biancheng 从右边数:b是第13个字符url="c.biancheng.net"
echo ${url:0-13} #省略length,直接截取到字符串末尾
>结果为:biancheng.net

从指定字符(子字符串)开始截取

这种截取方式无法指定字符串长度,只能从指定字符(子字符串)截取到字符串末尾。Shell可以截取指定字符(子字符串)右边的所有字符,也可以截取左边的所有字符

1)使用#号截取右边字符

使用#号可以截取指定字符(或子字符串)右边的所有字符,具体格式如下:

url="http://c.biancheng.net/index.html"
echo ${url#*:}>结果为://c.biancheng.net/index.htmlecho ${url#*p:}
echo ${url#*ttp:}

使用##可以直到最后一个指定字符(子字符串)再匹配结束

#!/bin/bash
url="http://c.biancheng.net/index.html"
echo ${url#*/}
# 结果为:/c.biancheng.net/index.html
echo ${url##*/}
# 结果为:index.html

2)使用%截取左边字符

使用%号可以截取指定字符(或者子字符串)左边的所有字符

四、Shell脚本语言的运算

4.1 算数运算

shell支持算术运算,但只支持整数,不支持小数

4.2 Bash中的算术运算
-- + 加法运算
-- - 减法运算
-- * 乘法运算
-- / 除法运算
-- % 取模,即取余数
-- ** 乘方 #乘法符号在有些场景需要转义
4.2 实现算术运算
[root@localhost ~]# echo "scale=3;20/3"|bc
6.666
[root@localhost ~]# echo "scale=3;2/3"|bc
.666
[root@localhost ~]# i=20
[root@localhost ~]# j=20
[root@localhost ~]# declare -i sum=i*j
[root@localhost ~]# echo $sum
400

内建的随机数生成器变量:

$RANDOM  取值范围:0-32767

[root@localhost ~]# echo $[$[$RANDOM%50]+1]
40
[root@localhost ~]# echo $[$RANDOM%50]
44
[root@localhost ~]# echo $[$[$RANDOM%50]+1]  #生成1~50之间的随机数
[root@localhost ~]# echo $[RANDOM % 100 + 1]

生成随机颜色字符串

[root@localhost ~]# echo -e "\033[1;$[RANDOM%7+31]mStudy\033[0m"
Study
[root@localhost ~]# echo -e "\033[1;$[RANDOM%7+31]mStudy\033[0m"
Study
4.3 增强型赋值:
[root@localhost ~]# let var+=1
[root@localhost ~]# echo $var
1
[root@localhost ~]# let var++
[root@localhost ~]# echo $var
2
[root@localhost ~]# let var-=1
[root@localhost ~]# echo $var
1
[root@localhost ~]# let var--
[root@localhost ~]# echo $var
0
[root@localhost ~]#[root@localhost ~]# unset i j ;i=1;let j=i++;echo "i=$i,j=$j" 
i=2,j=1
[root@localhost ~]# unset i j ;i=1;let j=++i;echo "i=$i,j=$j"
i=2,j=2

4.2 逻辑运算

True用数字表示1,False用数字表示0

http://www.lqws.cn/news/137521.html

相关文章:

  • [Java 基础]面向对象-多态
  • 关于物联网的基础知识(一)
  • 职坐标IT教育物联网全栈开发实战:传感器到云平台全链路
  • ‌RF Choke(射频扼流圈)
  • 第十三节:第二部分:集合框架:Map系列集合:概述、常用方法
  • thymeleaf直接调用Spring Bean中定义的方法
  • Python 开发效率秘籍:PyCharm、VS Code 与 Anaconda 配置与实战全解
  • 【会员专享数据】1960—2023年我国省市县三级逐年降水量数据(Shp/Excel格式)
  • UDP包大小与丢包率的关系:原理分析与优化实践
  • 解决el-cascader组件下拉选项过长,数据回显无法换行显示的问题
  • JavaScript中判断两个对象是否相同(所有属性的值是否都相同)
  • 电商接口计费标准是什么?
  • 数据“出国”需办“签证”: 如何申请数据出境安全评估?
  • 【二分图 图论】P9384 [THUPC 2023 决赛] 着色|普及+
  • Vue Router 导航方法完全指南
  • ShardingSphere 如何解决聚合统计、分页查询和join关联问题
  • DeepSeek+SpringAI实现流式对话
  • Python Day43
  • 脑机新手指南(四):新手小白入门 BCI-从认识到初体验(下)
  • Fluence推出“Pointless计划”:五种方式参与RWA算力资产新时代
  • 极客大挑战 2019 EasySQL 1(万能账号密码,SQL注入,HackBar)
  • Linux 云服务器部署 Flask 项目(含后台运行与 systemd 开机自启)
  • C#Winform中DevExpress下的datagridview 特定列可编辑,其他列不可编辑
  • 链表题解——环形链表【LeetCode】
  • iOS上传应用包错误问题 “Invalid bundle. The “UIInterfaceOrientationPortrait”“
  • Java时间API终极指南
  • 【输入URL到页面展示】
  • django paramiko 跳转登录
  • 【使用 Loki + Promtail + Grafana 搭建轻量级容器日志分析平台】
  • grafana 批量视图备份及恢复(含数据源)