Shell脚本教程

Shell脚本教程

1. Shell是什么

shell 是一种命令解释器,用户与操作系统内核之间的交互界面,当你登录了Linux后,看到的就是shell

shell其实这个脚本语言是使用C语言开发编写的

而我们通常所讲的bash ,其实是Shell的一种具体实现。在CentOS中,就是用bash 当做解释器的。

可以这样理解,Shell是一门编程语言,但是实现这门编程语言的方式可以有很多种,比如就是bash。

2.Shell脚本是什么?

怎么讲呢,shell脚本就是将多个Linux命令和逻辑循环控制语句,写在一个文件中,然后统一执行这个脚本。

shell脚本以.sh后缀结尾,但是Linux中后缀没什么作用,但是加上后缀可以让人知道你这个文件是干嘛的。

举个脚本的例子…新建一个文件 test.sh ,内容如下。

#!/bin/bash
echo "Hello world!!!"
echo "这是一个简单的shell脚本"
echo "#!/bin/bash 是告诉这个代码文件用哪个解释器来解释这些代码"
echo "#!是指定解释器,后面跟的就是具体的解释器路径"
# 比如写了一些python 代码,那么就要指定Python的解释器.
#!/usr/bin/python
print ("Hello World")

shell脚本的中的注释是以# 开头的,注释最好使用英文,中文也可以

3.Shell脚本的执行方式

  • bash script.shsh script.sh 适用文件本身没有执行权限或脚本未指定解释器 (重点推荐)
  • 适用 相对/绝对的路径来执行脚本,需要脚本文件具有可执行权限 例如 ./script.sh
  • source script.sh. script.sh 代表执行的意思,source 就等同于 .

shell 的数据类型默认都是字符串

shell脚本属于弱类型语言,无需声明数据类型,直接定义使用

4.Shell的变量

系统变量

  • 家目录下有自己的全局变量 ~/.bashrc ~/.bash_profile
  • 对每个用户都生效,就需要在root下修改/etc/profile文件

查看系统环境变量的命令

  • set 查看系统所有的系统变量,局部变量
  • env 只显示全局变量
  • declare : 如同set 一样,
  • export 显示和设置环境变量值

撤销环境变量

  • unset 变量名

设置只读变量

  • readonly # readonly age=“18”

特殊变量

# $0  获取脚本文件的名字 
# $n 获取shell脚本的位置参数  n在 1-9之间,大于9 要写 ${10}
# $# 获取shell脚本执行后面的参数的总个数
# $* 获取shell脚本的所有参数,不加引号等同于$@ 加上引号的作用,接受所有参数为单个字符串 "1 2 3 4 5"
# $@ 不加引号,效果同上,加引号,接受参数为独立的字符串 "1" "2" "3" "4" "5"

特殊状态变量

# $? 上一次命令的正确与否返回值,0 True 非0 Flase
# $$ 当前shell脚本的进程号
# $! 上一次后台进程的PID
# $_ 取上次命令传入的最后一个参数
man bash 去查看这些东西

5.Shell子串

bash 的一些内置命令

echo
eval
exec
export
read  从控制台读取输入
shift

echo命令

# echo 命令式默认换行输出的 echo "你好";echo "hello"
-n  不换行打印输出
-e  识别特殊符号  echo -e "我看你\n挺行"   # 识别\n换行符 
\n 换行
\r 回车
\t 制表格

eval命令

一次性执行多个命令
eval ls;cd /etc 

exec命令

# 不创建子进程,执行后续命令,且执行完毕后,自动 exit

shell子串的用法

name="abcdefg"
${变量} 返回变量值
${#变量} 返回变量长度 字符长度  echo ${#name}  7
${变量:start} 返回变量offset数值之后的字符  offset 是索引,从0开始  ${name:4} efg
${变量:start:length} 返回offset之后的length限制的字符 ${name:2:4} cdef  从2索引开始往后拿4个
${变量#word} 从变量开头删除最短匹配的word子串 ${name#a} bcdefg 匹配a 删调a
${变量##word} 从变量开头 删除最长匹配的word  ${name##a} bcdefg 
${变量%word} 从变量结尾删除最短匹配的word子串
${变量%%word} 从变量结尾删除最长匹配的word子串
${变量/pattern/string} 用string代替第一个匹配的pattern 
${变量//pattern/string} 用string 代替所有的paatern

计算机变量的长度的几种方式

# name="nihao180"
echo ${name} | wc -L # -L统计最长的行的长度
# 利用数值计算的命令 expr 计算长度
expr length "${name}"
# 利用awk来统计字符串的长度
echo "${name}" | awk '{print length($0)}' 
# 最快的统计方式
echo "${#name}"

批量文件名替换

# 假设 有五个文件分别是:  1_aaa.jpg 2_aaa.jpg 3_aaa.png 4_aaa.jpg 5_aaa.jpg
# 现在,替换 只以.jpg结尾的文件,去掉他们所有的 _aaa
for file_name in `ls *.jpg`;do mv ${file_name} `echo ${file_name//_aaa/}`;done

6. 特殊的Shell扩展变量

 这四个扩展变量,都属于对变量的值进行判断、处理# 如过 var 变量值为空,返回word字符串,赋给result 变量result=${var:-word}# 如果var为空,则word替代变量值,且返回其值(也就是将word的值返回给 var和result了)result=${var:=word}# 如果var 变量为空,word当做stderr输出,否则输出变量值# 用于设置变量为空导致错误时,返回的错误信息${var:?word}   #如果var变量为空,什么都不做,否则返回wordresult=${var:+word}

删除过期的备份文件

find xargs 搜索 且 删除
#删除过期7天的log日志
find ${dir_path:=/data/mysql_log} -name "*.tar.gz" -type f -mtime +7 | xargs rm -rf

7. 父子Shell

  1. source 和 点 , 执行脚本, 只在当前的shell环境中执行生效
  2. 指定 bash sh 解释器运行脚本,是开启了子shell运行的脚本命令
  3. ./script 一般是指定了shebang 也是通过解释器运行,也是开启了子shell运行命令

ps -ef --forest # 以层级关系展示进程的信息

8.内置命令 和 外置命令

内置命令:在系统启动的时候就加载到内存中,常驻内存,执行的效率高,缺点是占用资源

外置命令:系统需要自主的从硬盘中读取程序文件,再读取内存中执行。

内置命令有 cd pwd 等等 ,用type cd 就可以查看 内置命令不会产生子进程执行

外置命令就类似 nginx,我们需要手动去启动nginx这样子 ,外置命令一定会开启子进程执行

# 如何查看shell所有的内置命令
compgen -b

9. Shell脚本开发

$()

在括号中执行命令,并拿到命令的执行结果 echo “今天的日期是 $(date)”

9.1 shell数值计算

shell的一些基础命令,只支持整数的运算,不支持小数,bc的命令才支持

用于数值计算的命令

(()) 双小括号 用于数值计算的

[root@zabbix-server shell_project]# # 加减乘除
[root@zabbix-server shell_project]# echo $((3+1))
4
[root@zabbix-server shell_project]# echo $((4-1))
3
[root@zabbix-server shell_project]# echo $((4*2))
8
[root@zabbix-server shell_project]# echo $((4/2))
2
[root@zabbix-server shell_project]# echo $((4**3))
64
[root@zabbix-server shell_project]# echo $((7%3))
1[root@zabbix-server shell_project]# echo ((a=2**3))
-bash: 未预期的符号 `(' 附近有语法错误
[root@zabbix-server shell_project]# #要加$符号取值
[root@zabbix-server shell_project]# echo $((a=2**3))
8
[root@zabbix-server shell_project]# echo a=$((3**4))
a=81

9.2 let 运算命令

let等同于(()) 但是(())的效率更高
[root@zabbix-server shell_project]# num=5
[root@zabbix-server shell_project]# let num=num+1
[root@zabbix-server shell_project]# echo $num
6

9.3 expr命令

简单的计算器命令

# 它基于空格传入参数,并不是很好用,遇到一些特殊的运算符号,需要加转义才可以
# 基本的加减乘除运算
[root@zabbix-server ~]# expr 5 + 3
8
[root@zabbix-server ~]# expr 5 - 3
2
[root@zabbix-server ~]# expr 5 \* 3
15
[root@zabbix-server ~]# expr 6 \/ 3
2# 求长度
[root@zabbix-server ~]# expr length 123456
6
[root@zabbix-server ~]# expr length abcsdwdadad
11# 逻辑判断(0是错,1是正确)
[root@zabbix-server ~]# expr 5 \> 3
1
[root@zabbix-server ~]# expr 5 \< 3
0

9.4 bc命令

命令行计算器

[root@zabbix-server shell_project]# bc
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'. 
1+1
2
2*2
4
4/2
2
1-1
0
2.2+1.1
3.3# 结合管道符来计算
[root@zabbix-server shell_project] echo 5*4 | bc
20
[root@zabbix-server shell_project] num=5
[root@zabbix-server shell_project] echo $num*5 | bc
25# 计算1加到100的值
# 利用bc$ echo {1..100} # 用来生成1-100的数字,生成的中间有空格,我们把空格全都替换成+号,用tr命令
# tr命令,替换的命令, tr " " "+"  意思是把空格替换成+号$ echo {1..100} | tr " " "+" | bc
5050
$ seq -s " " 100 | tr " " "+" |bc

10.read命令

read命令参数

  • -p “设置提示信息”
  • -t “设置多长时间未输入的时间,也就是超时时间”
read -p "请你输入一个数字:"
read -t 5 -p  "五秒钟输入一个数字,不然就超时不让你输入了:"

11.shell条件测试

shell 提供的条件测试的语法

  • [ ] 中括号,最常用的
  • test命令 次常用

test 命令评估一个表达式,如果为真 ,$? 的值就是0 非零就是假

test 语法大全

# 1.关于文件名以及类型检测存在与否
$ -e[文件]是否存在(常用)    test -e /etc/aaa.txt
$ -f 该【文件属性】是否为文件(file)(常用) test -f /etc/bbb
$ -d 该【文件属性】是否为目录 (常用) test -d /home/ccc
$ -S 该【文件属性】是否为一个Socket文件# 2. 关于文件的权限侦测
$ -r 检测文件是否有可读的属性 test-r ./demo.sh
$ -w 是否可写  
$ -x 是否可执行
$ -u 是否有SUID属性
$ -g 是否有SGID属性
$ -s 是否为非空白文件   # 如果是里面有内容,$?的值是0 如果没内容 就是非零$ -z # 检测字符串如果是空字符串,则为真,否则为假
$ -n # 检测字符串如果有内容,则为真,否则为假

中括号的使用

中括号和test是一样一样的作用,你想用那个用哪个

注意:在条件测试中使用变量,必须必须必须添加双引号

[root@zabbix-server shell_project]# echo `[ -f ./demo.sh  ]` $?
0
[root@zabbix-server shell_project]# file1="hello.txt"
[root@zabbix-server shell_project]# echo `[-f "${file1}"]` $?
bash: [-f: 未找到命令...  # 千万注意,中括号两边必须必须必须有空格
127
[root@zabbix-server shell_project]# echo `[ -f  "${file1}" ]` $?
1

12.shell数值比较

在[] 以及test中使用的比较符号在(())和[[]]中使用的比较符号说明
-eq== 或 =相等,全拼为equal
-ne!=不相等,全拼为not equal
-gt>大于
-ge>=大于等于
-lt<小于
-le<=小于等于

如果想在[] 中使用 == 或者 != 等等这些比较符号,那么就必须必须必须添加转移符号才可以

[ 1 > 2 ] && echo "yes" || echo "no"  #这里的语法错误,因为>号没有被转义,是不对的
[ 1 \> 2 ] && echo "yes" || echo "no" # 这个是对的# 注意:这里使用!=这个符号,是不需要加转移符号的。

但是哦,我们test中使用这些数学比较符号,是不需要加转义符的…

双中括号和单中括号是一样的,但是但双括号在特殊场景下会有独特的作用,比如支持正则表达式

他两个的其他用法一模一样,最常用单中括号 []

12. 逻辑符号操作

&& 和 -a的作用都一样

|| 和 -o 的作用一样

在[] 以及test中使用的操作符在(())和[[]]中使用的操作符说明
-a&&and 两端都为真,结果为真
-o||or 或 两端有一个为真,结果为真
!!not 两端相反 则结果为真

13. 安装LAMP / LNMP脚本开发

# 这里不进行真正的安装这两个,只做一个演示
# 我在 /test_script 目录下创建两个演示脚本,LAMP.sh LNMP.sh ,并分别在其中打印一句话,并赋予执行权限。
# 然后在创建一个脚本来调用执行这两个脚本。
cd /test_script
vim LAMP.sh
--------------
#!/bin/bash
echo "正在安装LAMP......."
--------------
vim LNMP.sh
--------------
#!/bin/bash
echo "正在安装LNMP......."
--------------
# 添加执行权限
chmod +x ./*# 创建另外一个调用的脚本
touch Install.sh
chmod +x Install.sh
vim Install.sh
--------------------------------------------------------------------------------------
#!/bin/bash# 判断脚本目录是否存在
# 我们优先处理错误的情况
path=/test_script/
[ ! -d "$path" ] && mkdir -p $path# 提示内容写入
cat <<END1.[Install LAMP]2.[Install LNMP]3.[exit]
ENDread -p "please input you want number:" num# 根据num变量输入进行逻辑处理
expr $num + 1 &> /dev/null
#根据上面的代码的状态码判断用户是否输入的是数字
[ $? -ne 0 ] && {echo "你输入的内容必须在1,2,3之间"exit 1
}
# 判断输入的数字是否在1,2,3 之间(我们用正则表达式来解决)双括号支持正则表达式
[[ ! "$num" =~ [1-3] ]] && {echo "数字必须在1,2,3 之间"exit 4
}# 剩下的情况就是1,2,3 这三个数字的情况了,我们逐个判断
[ "$num" -eq "1" ] && {echo "开始安装LAMP.......请等待"sleep 2# 执行lamp脚本安装# 判断文件权限是否有可执行的权限[ -x "$path/LAMP.sh" ] || {echo "文件不存在,或者没权限"exit 1}$path/LAMP.shexit $?
}[ "$num" -eq "2" ] && {echo "开始安装LNMP.......请等待"sleep 2# 执行lamp脚本安装# 判断文件权限是否有可执行的权限[ -x "$path/LNMP.sh" ] || {echo "文件不存在,或者没权限"exit 1}$path/LNMP.shexit $?
}[ "$num" -eq "3" ] && {echo "byebye"exit
}
--------------------------------------------------------------------------------------
# 然后执行测试即可

14.if语句

14.1 单分支if 语句

#!/bin/bashif [ "1" -eq "1" ];thenecho "Yes"
fi
# 记得fi闭合

14.2 单/多分支if语句

if [ "1" -eq "1" ];thenecho "Yes"
elseecho "No"
fiif [ -f /etc/hosts ];thenecho "存在"
elif [-d /etc];thenecho "存在"
elseecho "不存在"
fi

开发内存监控脚本

# 1.检测linux可用内存,如果小于100M,则提示警告发邮件
# 2.并且加入crontab,每三分钟检测一次(定时任务)
# 1. 通过free -m 命令取available的值,通过awk命令提取
free -m | awk 'NR==2{print $NF}'# 2.开发脚本
-----------------------------------------------------------------
#!/bin/bashFreeMem=`free -m | awk 'NR==2{print $NF}'`
chars="可用内存是: $FreeMem"if [ "$FreeMem" -lt "100" ];thenecho "$chars"echo "内存不足,及时检查"
fi
-----------------------------------------------------------------# 设置每三分钟执行一次
# 意思是,*/3 每三分钟
# 用/bin/bash 这个解释器来执行 /test_script/free.sh这个脚本
# 将脚本的输出写入到黑洞文件里去
crontab -e
*/3 * * * *  bin/bash /test_script/free.sh &> /dev/null

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/792999.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

算法实验二 矩阵最小路径和 LIS

算法实验课二 矩阵最小路径和 leetcode裸题 最小路径和 给定一个包含非负整数的 *m* x *n* 网格 grid &#xff0c;请找出一条从左上角到右下角的路径&#xff0c;使得路径上的数字总和为最小。 说明&#xff1a;每次只能向下或者向右移动一步。 示例 1&#xff1a; 输入&…

算法 - 符号表-上

&#x1f3e0;个人主页&#xff1a;尘觉主页 文章目录 算法 - 符号表前言初级实现1. 链表实现无序符号表2. 二分查找实现有序符号表 二叉查找树1. get()2. put()3. 分析4. floor()5. rank()6. min()7. deleteMin()8. delete()9. keys()10. 分析 算法 - 符号表 前言 符号表&am…

intellij idea 使用git撤销(取消)commit

git撤销(取消) 未 push的 commit Git&#xff0c;选择分支后&#xff0c;右键 Undo Commit &#xff0c;会把这个 commit 撤销。 git撤销(取消) 已经 push 的 commit 备份分支内容&#xff1a; 选中分支&#xff0c; 新建 分支&#xff0c;避免后续因为操作不当&#xff0c;导…

iOS-App:App Store新的审核政策,在应用隐私清单中声明和解释使用特定API的原因

App Store新的审核政策&#xff0c;在应用隐私清单中声明和解释使用特定API的原因 设备/引擎&#xff1a;Mac&#xff08;11.6&#xff09;/Mac Mini 开发工具&#xff1a;终端 开发需求&#xff1a;苹果官方邮件通知&#xff0c; App Store新的审核政策&#xff0c;在应用隐…

【Java笔记】多线程0:JVM线程是用户态还是内核态?Java 线程与OS线程的联系

文章目录 JVM线程是用户态线程还是内核态线程什么是用户态线程与内核态线程绿色线程绿色线程的缺点 线程映射稍微回顾下线程映射模型JVM线程映射 线程状态操作系统的线程状态JVM的线程状态JVM线程与OS线程的状态关系 Reference 今天复盘一下Java中&#xff0c;JVM线程与实际操作…

CCIE-08-BGP-Listen

目录 实验条件网络拓朴实验目的 开始配置配置动态路由协议配置BGP检查邻居配置 实验条件 网络拓朴 实验目的 将R1配置成Listen状态&#xff0c;自动接收来自其它路由器的建邻居请求、建立邻居 开始配置 配置动态路由协议 这里用EIGRP来配置&#xff0c;保证网络的可达性&a…

替代 Redis 和 Memcached:25 倍吞吐量! | 开源日报 No.213

dragonflydb/dragonfly Stars: 22.4k License: NOASSERTION Dragonfly 是一个内存数据存储&#xff0c;适用于现代应用工作负载&#xff0c;可替代 Redis 和 Memcached。与传统的内存数据存储相比&#xff0c;Dragonfly 提供了 25 倍的吞吐量、更高的缓存命中率和更低尾部延…

基于springboot的粮仓管理系统

文章目录 项目介绍主要功能截图&#xff1a;部分代码展示设计总结项目获取方式 &#x1f345; 作者主页&#xff1a;超级无敌暴龙战士塔塔开 &#x1f345; 简介&#xff1a;Java领域优质创作者&#x1f3c6;、 简历模板、学习资料、面试题库【关注我&#xff0c;都给你】 &…

java数组.day16(冒泡排序,稀疏数组)

冒泡排序 冒泡排序无疑是最为出名的排序算法之一&#xff0c;总共有八大排序! 冒泡的代码还是相当简单的&#xff0c;两层循环&#xff0c;外层冒泡轮数&#xff0c;里层依次比较&#xff0c;江湖中人人尽皆知。 我们看到嵌套循环&#xff0c;应该立马就可以得出这个算法的时…

TensorBoard可视化+Confustion Matrix Drawing

for later~ 代码阅读 1. 加载trainset import argparse import logging import os import numpy as npimport torch from torch import distributed from torch.utils.data import DataLoader from torch.utils.tensorboard import SummaryWriterfrom backbones import get_…

2024年150道高频Java面试题(十七)

33. Stream API 在 Java 8 中是如何简化集合操作的 Java 8 引入的 Stream API 是一个强大的新特性&#xff0c;它极大地简化了集合操作的复杂性&#xff0c;提高了代码的可读性和效率。Stream API 允许开发人员以声明式的方式处理数据集合&#xff08;比如集合、数组等&#x…

1.Spring Boot框架整合

Spring Boot项目创建&#xff08;约定大于配置&#xff09; 2.1.3.RELEASE版本示例 idea创建 从官网下载&#xff08;https://start.spring.io/&#xff09;单元测试默认依赖不对时&#xff0c;直接删除即可 Web支持&#xff08;SpringMVC&#xff09; <dependency>&…

Collection与数据结构 链表与LinkedList(三):链表精选OJ例题(下)

1. 分割链表 OJ链接 class Solution {public ListNode partition(ListNode head, int x) {if(head null){return null;//空链表的情况}ListNode cur head;ListNode formerhead null;ListNode formerend null;ListNode latterhead null;ListNode latterend null;//定义…

见证历史:Quantinuum与微软取得突破性进展,开启了可靠量子计算的新时代!

Quantinuum与微软的合作取得了重大突破&#xff0c;将可靠量子计算带入了新的时代。他们结合了Quantinuum的System Model H2量子计算机和微软创新的量子比特虚拟化系统&#xff0c;在逻辑量子比特领域取得了800倍于物理电路错误率的突破。这一创新不仅影响深远&#xff0c;加速…

Java中Stream流介绍

Java 8引入的Stream API是Java中处理集合的一种高效方式&#xff0c;它提供了一种高级的迭代方式&#xff0c;允许你以声明式方式处理数据。Stream API可以对数据执行复杂的查询操作&#xff0c;而不需要编写冗长且复杂的循环语句。下面是一些使用Stream API的常见场景和示例&a…

Python数据分析与可视化笔记 九 分类问题

分类 分类是找出数据库中一组数据对象的共同特点&#xff0c;并按照分类模式将其划分为不同的类&#xff0c;其目的是通过分类模型&#xff0c;将数据库中的数据项映射到某个给定的类别。 分类学习是一类监督学习的问题&#xff0c;训练数据会包含其分类结果&#xff0c;根据分…

设计模式面试题(二)

1.单例优缺点 单例模式是一种常用的设计模式&#xff0c;它确保一个类仅有一个实例&#xff0c;并提供一个全局访问点。单例模式的使用具有一定的优点&#xff0c;同时也伴随着一些潜在的缺点。 优点 资源控制&#xff1a;单例模式能够确保资源如数据库连接或文件系统的一致…

目标检测——监控下的汽车

一、重要性及意义 首先&#xff0c;车辆检测技术是保证视频监控系统正常运行的基础。通过监控摄像头实时获取的图像&#xff0c;可以自动检测出图像中的车辆&#xff0c;并进行车辆类型的分类和识别。这对于优化城市交通管理、实现智能交通系统具有重要意义。此外&#xff0c;…

【无标题】html中使用div标签的坏处

在HTML中使用<div>作为布局元素时&#xff0c;尽管它已经成为现代Web开发的标准做法之一&#xff0c;并且与CSS结合使用可以实现灵活、语义化的布局设计&#xff0c;但也存在以下潜在的坏处或挑战&#xff1a; 复杂度增加&#xff1a; - 学习曲线&#xff1a;对于初学者…

【SQL Server的详细使用教程】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…