Linux中shell脚本详解

文章目录

      • 1、第一个脚本程序:
      • 2、shell获取字符串长度:
      • 3、shell变量:
      • 4、**引用shell变量**:
      • 5、shell变量的赋值、修改、删除:
      • 5、shell特殊变量:
      • 6、shell中字符串的拼接:
      • **7、字符串的截取**
      • 8、shell中的数组:
      • 9、shell中条件判断if:
      • 10、shell中的 case语句:
      • 11、shell中的 for循环:
      • 12、shell中的 while循环:
      • 13、shell中的 until循环:
      • 14、shell循环中的break和continue:
      • 15、shell中的函数:

Shell:一般我们是用图形界面和命令去控制计算机,真正能够控制计算机硬件(CPU、内存、显示器等)的只有操作系统内核(Kernel),由于安全、复杂、繁琐等原因,用户不能直接接触内核,需要另外再开发一个程序,让用户直接使用这个程序;该程序的作用就是接收用户的操作(点击图标、输入命令),并进行简单的处理,然后再传递给内核,内核和用户之间就多了一层“中间代理”,Shell 其实就是一种脚本语言,也是一个可以用来连接内核和用户的软件,我们编写完源码后不用编译,直接运行源码即可。

常用的Shell:bash由 GNU 组织开发,sh 是 UNIX 上的标准 shell,是第一个流行的 Shell,bash保持了对 sh shell 的兼容性,是各种 Linux 发行版默认配置的 shell。现在sh 已经基本被 bash 代替,bash是sh的扩展补充,但是也有些是不兼容的,大多数情况下区别不大,特殊场景可以使用 bash 代替 sh。

img

在ubuntu下,上图是我们打开的终端,这里输入的命令就是我们shell的命令,一般$表示的是普通用户,而#表示的是超级用户(root)

1、第一个脚本程序:

在终端创建一个.sh文件,vi test.sh

img

第一行,#!是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,用的是哪种shell,后面的/bin/bash就是指明了解释器的具体位置。
第二行#是注释行,用来解释说明,当然#!是特殊的,不在此类。 第三行在是终端输出 hello,is me!

img

执行shell脚本:

./test.sh: ./表示当前目录,执行./test.sh会说明权限不够,不能执行。需要改变文件的权限:chmod 777 test.sh,就能执行

. ./test.sh: 在不想改变权限的时候,测试脚本是不是能够正常使用。. 临时增加权限。

2、shell获取字符串长度:

#!/bin/bash
#获取字符串长度
str="123456"
echo "${#str}"

结果:

img

3、shell变量:

在bash shell中,每一个变量的值都是字符串, 当然也可以用declare 关键字显式定义变量的类型,在赋值的时候等号两边不能有空格,如:str=1 ,str=‘1’ ,str=“1”,变量名必须有字母、下划线、数字组成,开头必须字母或者下划线,不能用shell。

  • 局部变量:shell也有自定义函数,函数里面的变量为局部变量,但是它也是相当于全局变量,函数中的变量,在函数外调用也是可以的,如果要仅限函数使用,需要在函数变量前加个关键字:local
  • 全局变量:每打开一个终端就是一个shell会话,在这个shell会话(终端)定义的变量就是全局变量,它在这个shell会话有效,当你打开另一个终端就是另一个shell会话,这个变量在另一个终端就失效了。
  • 环境变量:在全局变量前加 export ,如:export a=1 那么这个变量就是环境变量了。创建这个变量的shell成为父shell,这个shell中,在创建一个shell叫做子shell,环境变量可以由父shell往下一级一级传,而不能逆转往上传递。当shell会话销毁时,这个环境变量也会随之销毁。想要永久保存就得环境变量写到启动文件中去。

4、引用shell变量

使用shell变量在变量前面加一个$,而标准的是 &{},目的是在一长串字符中可以识别出这个变量,而不会引起误会,如下:

#!/bin/bash
#引用shell变量
str="abc"echo "$str"
echo "the str vaile is: $str1" 
#后面增加一个1,就不能正确的识别变量
echo "the str vaile is: ${str}1"
#所以我们引用变量,最好统一用 ${} 的形式

结果:

img

5、shell变量的赋值、修改、删除:

a)、shell变量的赋值

#!/bin/bash
#变量的赋值
n=1
v1=${n}
v2='${n}'
v3="${n}"echo "${v1}"
echo "${v2}"
echo "${v3}"

img

可以从结果看出不加引号和加双引号的结果是相同的,而单引号是原样输出变量后面赋值的内容。

b、shell变量的修改、删除:

#!/bin/bash
#变量值的修改
a=1
echo "a: ${a}"
a=2
echo "a: ${a}"#只读变量是不可以修改的,在变量前加readonly,就是只读变量
c=1
echo "c: ${c}"
readonly c
c=2
echo "c: ${c}"#只要在变量前面加一个 unset,如: unset a   就可以删除变量。
unset a
echo "a: ${a}"

img

5、shell特殊变量:

$0当前脚本的文件名或者解释器。
$n(n≥1)传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,第一个参数是 $1,第二个参数是 $2。
$#传递给脚本或函数的参数个数。
$*传递给脚本或函数的所有参数。
$@传递给脚本或函数的所有参数。当被双引号" "包含时,$@ 与 ∗稍有不同,* 稍有不同,*的所有参数是一个数据,而$@一个参数就是一份数据
$?上个命令的退出状态,或函数的返回值
$$当前 Shell 进程 ID。对于 Shell 脚本,就是这些脚本所在的进程 ID。

**脚本:**如果参数个数太多,达到或者超过了 10 个,那么就得用${n}的形式来接收了,例如 ${10}${11}

#!/bin/bash
#shell特殊变量
#$n: $0表示本脚本,$1表示输入的第一个参数:11,$2表示输入的第一个参数:22    
echo "$ 0: $0"
echo "a: $1"
echo "b: $2"
#$*: 输入的参数 11 22
echo "$ *: $*"
#$@: 输入的参数 11 22
echo "$ @: $@"
#$$: shell进程id
echo "$ $: $$"
#$#: 参数个数 2
echo "$ #: $#"

img

函数:如果参数个数太多,达到或者超过了 10 个,那么就得用${n}的形式来接收了,例如 ${10}${11}

#!/bin/bash
#shell特殊变量
#$n: $0表示本脚本,$1表示输入的第一个参数:11,$2表示输入的第一个参数:22    
function temp(){echo "$ 0: $0"echo "a: $1"echo "b: $2"#$*: 输入的参数 11 22echo "$ *: $*"#$@: 输入的参数 11 22echo "$ @: $@"#$$: shell进程idecho "$ $: $$"#$#: 参数个数 2echo "$ #: $#"}temp 11 12

img

$?:上一个命令的退出状态,或者返回值:

#!/bin/bashif [ $1 == 11 ]
thenreturn 0
elsereturn 1
fi

img

$?在shell函数中的应用:

#!/bin/bash
function temp(){return $1
}
temp 3#$?: 这里是函数的返回值
echo "$ ?: $?"

img

6、shell中字符串的拼接:

#!/bin/bash
#shell字符串的拼接
n1=ab
n2=cdtemp1=${n1}${n2}  #中间不能有空格 
temp2="${n1}${n2}"
temp3="${n1}cdefg"echo "${temp1}"
echo "${temp2}"
echo "${temp3}"

img

7、字符串的截取

  • ${string: start :length}:字符串从左边start开始的位置截取length个字符,如果没有length,就从左边start开始到结束
  • ${string: 0-start :length}:字符串从右边start开始的位置截取length个字符,如果没有length,就从右边数start开始到结束
  • ${string#*chars}:字符串从边开始的第一个chars开始的位置截取到边结束,chars本身不在截取范围内
  • ${string##*chars}:字符串从边开始的最后一个chars开始的位置截取到边结束,chars本身不在截取范围内
  • ${string%*chars}:字符串从边边开始的第一个chars开始的位置截取到边结束,chars本身不在截取范围内
  • ${string%%*chars}:字符串从边开始的最后一个chars开始的位置截取到边结束,chars本身不在截取范围内
#!/bin/bash
#shell截取字符串str=http//:baidu.com/.cecho "length: ${str:7:5}"   # baidu
echo "no length: ${str:7}"  # baidu.com/.cecho "length: ${str:0-7:5}"  # .com/
echo "no length: ${str:0-7}" # .com/.cecho "#: ${str#*/}"   # /:baidu.com/.c
echo "##: ${str##*/}" # .cecho "%: ${str%/*}"   # http//:baidu.com
echo "%%: ${str%%/*}" # http

img

8、shell中的数组:

bash shell 中只支持一维,而不支持二维,定义的形式:array=(n1 n2 n3) ,数组名等号两边不能有空格,数组变量的值用空格隔开表示不同的值,一个数组变量的值可以用数字或者字符串不同的形式组成:array=(1 2 ab) 。

Shell 数组的长度不是固定的,定义之后还可以增加元素,如:array[3]=cd ;就在最后增加了一个元素。

也不用逐个赋值;如:array=([2]=ab);但他的长度是1

调用数组:

  • ${array[0]}
  • a=${array[0]}
  • ${array[*]} //表示数组的所有元素
  • ${array[@]} //表示数组的所有元素
#!/bin/bash
#shell中的数组
array=( 1 2 ab)n=${array}  #array中的第一个元素赋值给necho "array[0]: ${array[0]}"
echo "array[*]: ${array[*]}"
echo "n[*]: ${n[*]}"array[5]=cd
echo "array[5]: ${array[5]}"
echo "array[@]: ${array[@]}"

img

获取shell数组的元素个数或者shell数组里字符串的长度:${#array[*]}、${#array[@]}、${#array[4]}

#!/bin/bash
#shell中的数组
array=( 1 2 abc)echo "#array[*] ${#array[*]}"array[4]=12345
echo "#array[@] ${#array[*]}" #这边多加了一个元素就是4
echo "#array[4] ${#array[4]}" #这边是计算array[4]中字符串的长度

img

数组的拼接:利用${array[*]}、${array[@]}

#!/bin/bash
#shell中的数组的拼接
array1=( 1 2 abc)
array2=(cd ef)
array3=(${array1[@]} ${array2[@]})echo "array3: ${array3[@]}"
echo "array3 length: ${#array3[@]}"

img

shell数组元素的删除:unset

#!/bin/bash
#shell中的数组
array1=(1 2 abc)
array2=(1 2 abc)unset array1[2]  #删除array1数组中的一个元素abc
echo "array1[*]: ${array1[*]}"unset array2  #删除整个数组array2
echo "array2[*]: ${array2[*]}"

img

9、shell中条件判断if:

a)、if单分支:

-eq 等于,如:if [ “$a” -eq “$b” ]

-ne 不等于,如:if [ “$a” -ne “$b” ]

-gt 大于,如:if [ “$a” -gt “$b” ]

-ge 大于等于,如:if [ “$a” -ge “$b” ]

-lt 小于,如:if [ “$a” -lt “$b” ]

-le 小于等于,如:if [ “$a” -le “$b” ]

#!/bin/bash
#shell中if:
#if单分支第一中形式:if []
if [ 1 -eq 1 ] #[]里面的数据和中括号必须一个空格 
thenecho "first if:真"
fi#if单分支第二中形式:if []; then
if [ 1 -eq 1 ]; then #then和if写在同一行必须要用; echo "second if:真"
fi#if单分支第三中形式:if (())
if ((1==1))
thenecho "third if:真"
fi

img

b、双分支if:

#!/bin/bash
#shell中if:
#if双分支
if ((1==0)) #判断1和o是不是相等
thenecho "我是真的"
elseecho "我是假的"
fi#................................
if [ 1 -eq 0 ] #判断1和o是不是相等,
thenecho "我是真的"
elseecho "我是假的"
fi

img

3、iif多分支:

#!/bin/bash
#shell中if:
#if多分支
if ((1==0)) #判断1和o是不是相等
thenecho "1=0;是真的"
elif ((1>0))
thenecho "1>0;是真的"
elseecho "1>0;是假的"
fi#..............................
if [ 1 -eq 0 ] #判断1和o是不是相等
thenecho "1=0;是真的"
elif [ 1 -gt 0 ]
thenecho "1>0;是真的"
elseecho "1>0;是假的"
fi

img

10、shell中的 case语句:

#!/bin/bash
#shell中的caseread VAILE #在屏幕中输入一个数,1或者2,如果不是这两个数就代表其他;即 *),
case ${VAILE} in"1")echo "我是1";;"2")echo "我是2";;*)echo "我不是1,也不是2";;
esac

img

11、shell中的 for循环:

a)、for循环形式1:

#!/bin/bash
#shell中的 for
for n in 1 3 5  #n是我们自定义的变量,in后面三个数就是循环3次,每次的值从第一个数的值开始
doecho "我是n,我的值是:${n}"
done

img

b)、for循环形式2:与c语言的形式类似

#!/bin/bash
#shell中的 for
for ((n=0;n<3;n++))
doecho "我是n,我的值是:${n}"
done

img

12、shell中的 while循环:

#!/bin/bash
#shell中的 while
n=0
while [ ${n} -lt 2 ] #n<2;就循环,否则退出循环
don=$((${n}+1))echo "我是n,我的值是:${n}"
doneecho "我退出循环了"

img

13、shell中的 until循环:

#!/bin/bash
#shell中的 until
n=-2
until ((n>1)) #不满足条件就循环,满足条件则退出循环
don=$((${n}+1))echo "我是n,我的值是:${n}"
doneecho "我退出循环了"

img

14、shell循环中的break和continue:

#!/bin/bash
#shell中的 break/continue
n=0
while ((n<6)) #n<6;就循环,否则退出循环
don=$((${n}+1))if ((n==2))thenecho "我应该打印2,但我continue了"continuefiif ((n==5))thenecho "n循环6次,应该等于6,但我break了,我现在的值是:${n}"breakfiecho "我是n,我的值是:${n}"doneecho "我退出循环了"

img

15、shell中的函数:

function 函数名(){

}

#!/bin/bash
#shell中的函数
function fun(){if(($1 > 1)); thenecho "条件成立"fiif(($2 > 1)); thenecho "条件成立"elseecho "条件不成立"fi
}fun 2 1   #这边传参数给fun()函数

img

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

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

相关文章

java递归实现多级菜单栏_Java构建树形菜单以及支持多级菜单的实例代码

这篇文章主要介绍了Java构建树形菜单的实例代码(支持多级菜单),非常不错&#xff0c;具有参考借鉴价值&#xff0c;需要的朋友可以参考下效果图&#xff1a;支持多级菜单。菜单实体类&#xff1a;public class Menu {// 菜单idprivate String id;// 菜单名称private String nam…

java中clone方法的理解(深拷贝、浅拷贝)

文章目录前言&#xff1a;知识点一&#xff1a;什么是浅拷贝&#xff1f;知识点二&#xff1a;什么是深拷贝&#xff1f;知识点三、java拷贝&#xff08;clone&#xff09;的前提&#xff1a;知识点四&#xff1a;浅拷贝案例&#xff1a;拷贝类&#xff1a;测试类&#xff1a;总…

mysql实现内容加密_简单为mysql 实现透明加密方法

一般用户在数据库中保存数据&#xff0c;虽然数据库存储的是二进制&#xff0c;无法直接明文打开查看&#xff0c;但是如果是一个外行人&#xff0c;直接连接进入mysql中&#xff0c;还是可以直接查看数据的。所以对于一些核心数据&#xff0c;特别是企业重要数据资产&#xff…

Java之AQS(AbstractQueuedSynchronizer)

Java之AQS&#xff08;AbstractQueuedSynchronizer&#xff09; AQS 介绍 AQS 的全称为 AbstractQueuedSynchronizer &#xff0c;翻译过来的意思就是抽象队列同步器。这个类在 java.util.concurrent.locks 包下面。 ● 是用来实现锁或者其他同步器组件的公共基础部分的抽象实…

SpringBoot 3.0最低版本要求的JDK 17,这几个新特性不能不知道

最近&#xff0c;有很多人在传说 SpringBoot要出3.0的版本了&#xff0c;并且宣布不再支持 Java 8&#xff0c;最低要求是 Java 17了。 其实&#xff0c;早在2021年9月份&#xff0c;关于 Spring Framework 6.0的消息出来的时候&#xff0c;Spring 官方就已经明确了不会向下兼…

jmeter mysql数据导出_Jmeter连接mysql

一、下载添加jar包image.png添加方法&#xff1a;1.拷贝到jmeter/lib目录下&#xff0c;此方法需重启jmeter2.直接在jmeter的测试计划中导入image.png二、连接mysql数据库添加配置元件-JDBC Connection Configurationimage.pngimage.png1.Variable Name for created pool&#…

判断一个坐标点是否在不规则多边形内部的算法

参考&#xff1a;https://wrf.ecse.rpi.edu//Research/Short_Notes/pnpoly.html 在GIS&#xff08;地理信息管理系统&#xff09;中&#xff0c;判断一个坐标是否在多边形内部是个经常要遇到的问题。乍听起来还挺复杂。根据W. Randolph Franklin 提出的PNPoly算法&#xff0c;…

mysql++多版本安装_MySQL多版本多实例安装启动

多版本&#xff0c;大版本不同测试多实例&#xff0c;一个MySQL5.7.30一个MySQL8.0.20解压8.0tar -xvf mysql-8.0.20-linux-glibc2.12-x86_64.tartar -xJf mysql-8.0.20-linux-glibc2.12-x86_64.tar.xz改名移动/mysql8.0.20mv mysql-8.0.20-linux-glibc2.12-x86_64 /mysql8.0.2…

cheungssh mysql密码_CheungSSH安装及基本使用

CheungSSH比Ansible的使用更简单&#xff0c;尤其是配置方面&#xff01;而Ansible有的功能&#xff0c; 我的这个程序一样有&#xff0c;和Ansible一样是python开发&#xff0c; 所以跟Ansible的模式一样&#xff0c; 但是CheungSSH 操作更简单&#xff01;配置更轻量&#xf…

mybatis group by 分组查询:将返回结果封装为map

文章目录1. 最简单但性能最差的做法2. 使用group by分组查询&#xff0c;将查询结果封装成类3.group by分组查询&#xff0c;将结果封装为map。直接封装为map&#xff1f;List1. 最简单但性能最差的做法 在逻辑层分多次对数据库进行查询。伪代码如下。 List<String> na…

esl证明函 oracle_强弱分明 Astralis证明之战—ESL科隆B组浅析

HLTV排名前16名中的13支队伍(缺席的是G2和North)将齐聚这座坐落在莱茵河畔的城市进行厮杀&#xff0c;争夺比赛的最高荣誉。这项赛事也是继今年卡托维茨Major以来含金量最高&#xff0c;强队参赛最多的线下赛事。下面我们就来分析一下B组的出线形势。B组分组*本次比赛的赛制依旧…

关于new ArrayList()和Collections.emptyList()

很明显 new ArrayList()是创建一个Collection实例&#xff0c;它是Collection集合下面的一个实现类&#xff08;中间继承了AbstractList&#xff09;&#xff0c;它的实例有Collection的增加&#xff0c;删除&#xff0c;修改等方法&#xff0c; ArrayList平常用的很多&#x…

ArrayList()和Collections.emptyList()的区别emptyList()、emptySet()、emptyMap()的作用和好处以及要注意的地方

前言 Java中ArrayList或许是我们平时开发最常用的一个集合类了&#xff0c;其次是HashMap&#xff0c;基本上满足了业务开发的绝大多数场景。今天要说的就是Collections.emptyList()和new ArrayList()的区别以及注意事项。 先来一段代码 运行main方法&#xff0c;会有如下输出…

基于mysql搭建框架环境搭建_Maven+Spring+Spring MVC+MyBatis+MySQL,搭建SSM框架环境

项目建设完成之后的结构&#xff1a;数据库的表结构如下&#xff1a;环境建设&#xff1a;搭建Maven环境、Tomcat环境、需要MySql 数据库支持&#xff0c;使用的编程工具Eclipse (这些是前期准备)&#xff1b;开始创建工程&#xff1a;1.创建一个Maven工程&#xff1a;选择weba…

DataIntegrityViolationException: Error attempting to get column处理方案汇总

项目背景 项目整体采用的是springbootmybatis 方式。有一次做数据查询的时候。console突然报&#xff1a;DataIntegrityViolationException: Error attempting to get column ‘xx’…异常。起初没在意。以为是xml中的SQL写错了&#xff0c;排查了没问题。百度一下这个报错&…

Mybatis原理:结果集封装详解

​ 经过sql参数解析、sql动态组装和执行sql&#xff0c;相对而言&#xff0c;结果集的封装&#xff0c;是mybatis数据处理的最后一环。这里只对查询结果而言&#xff0c;因为更新语句一般都是返回影响的行数。抛开mybatis&#xff0c;如果让我们组装结果&#xff0c;我们该如何…

python内置函数面向对象_Pyhton——面向对象进阶二:类的内置函数补充、描述符...

Pyhton——面向对象进阶二&#xff1a;一、类的内置函数补充1、isinstance(obj,cls)——检查obj是否是该类的对象class Hoo:def __init__(self,name,tem):self.name nameself.tem temclass foo(Hoo):passf1foo(e,20)print(isinstance(f1,Hoo))首先 f1 肯定是 foo 的对象&…

vue项目打包后部署到服务器(超详细步骤)

耽误了几天, 终于开始写第二篇博客了, 这篇会讲怎么将vue项目打包部署到服务器, 其实和上一篇的uni-app步骤一样的, 就是最后多了一步修改nginx配置, 好 , 上操作 一 ,打包项目 vscode下载链接&#xff1a;https://pan.baidu.com/s/1ibHt7XB6EZy37BDb1CigWw 提取码&#xff1…

postman怎么不登陆使用_最新百度云不限速,免安装、免登陆、不限速,打开网站就能使用...

上次给大家安利了一波Pandownload手机版/电脑版。那篇文章中也说了&#xff0c;这类应用使用不当可能会遇到账号被限速的情况&#xff0c;而且手机版必须登录才能进行不限速下载。总之&#xff0c;凡是没登录账号的小伙伴&#xff0c;下载过程会非常曲折。那么是否有无需登录就…

vue项目配置打包测试环境/生产环境

vue项目配置打包测试环境/生产环境&#xff1a; 开发环境运行命令&#xff1a;npm run serve 生产环境打包命令&#xff1a;npm run pro 测试环境打包命令&#xff1a;npm run build 步骤&#xff1a; 1.项目中添加一个配置ip的js文件&#xff0c;比如如下的ip-config.js&…