shell脚本

目录

一、编程语言的分类

二、shell

【1】第一个shell脚本

【2】常见的shell解析器

【3】运行脚本的3种方式

i)bash

ii)source

iii)直接给脚本添加可执行权限

三、修改环境变量

【1】如何查看系统提供的环境变量

【2】查看PATH变量

【3】修改PATH路径

i)只对当前终端生效

 ii)只对当前用户生效 ---->修改家目录下的文件

iii)对所有用户都生效的方式

iv)对所有用户生效

四、shell中的变量

【1】定义变量

【2】使用变量

【3】变量的赋值

五、shell中的数组

【1】定义

【2】数组中元素的访问 

练习:

 【3】使用已有的数组给新的数组赋值

六、shell中的输入输出

【1】输出--->echo

 【2】read

练习:

七、shell中的算术运算

【1】(())

练习:

【2】$[]实现算数运算

练习:

【3】let实现算数运算

【4】expr

练习:

练习:

八、shell中的分支语句

【1】if···else分支

余下见链接

练习:


一、编程语言的分类

编译型语言:C、C++ ------>需要编译器

解释型语言:shell、python ------>需要解析器

二、shell

shell---->贝壳

shell解析器:起到保护内核的作用,用户无法直接和内核层交换,通过指令和shell解析器完成用户和内核的交互

应用层:代码
---------------------------     shell解析器
内核层:
    内核层的五大功能:
        1、内存管理
        2、网络管理
        3、进程管理
        4、文件管理
        5、设备管理 
---------------------------
硬件层:外部设备

【1】第一个shell脚本

hello.sh ---->后缀是.sh

#!/bin/bash
#   #!---->shebang 
# 指明脚本运行使用的shell解析器


#这是一行注释
echo "第一个shell脚本"

【2】常见的shell解析器

bash:现在市面上大部分linux都使用bash解析器

dash:比bash功能更少一点

sh:和终端的交互性不好

csh:类似C语言的模式

如何查看本机使用的shell解析器:echo $SHELL

【3】运行脚本的3种方式

i)bash

bash 文件名.sh     ------>使用shell解析器去解析脚本
bash在运行脚本时,会在后台打开一个新的终端,把运行的结果返回到当前终端

ii)source

source是一个终端指令

source 文件名.sh source在同一个终端上运行和输出结果

iii)直接给脚本添加可执行权限

chmod 777 脚本名

./脚本名

三、修改环境变量

【1】如何查看系统提供的环境变量

env ---->回显所有系统提供的环境变量

【2】查看PATH变量

echo $PATH

PATH的作用,在终端执行指令或程序时,默认在PATH包含的路径中查找,如果程序/指令的路径不在PATH中,就会执行失败(未找到该命令)

修改PATH之后,可以直接输入可执行程序名执行程序,不需要再加上路径

【3】修改PATH路径

一定不能修改原有的PATH路径

i)只对当前终端生效

export PATH=${PATH}:新的路径
export PATH=${PATH}:/home/ubuntu/23061/day2
export             PATH        =     ${PATH}            :        /home/ubuntu/23061/day2
  |                  |         |        |               |             |
给(系统)变量赋值  要赋值的变量  赋值  拿到原有的PATH的值  路径分隔符  追加的新路径

 ii)只对当前用户生效 ---->修改家目录下的文件

vim ~/.bashrc  --->打开用户的配置文件,把想要添加的路径使用export表达式添加到最后一行

让配置文件生效:

  1. 重启(永久生效)
  2. source ~/.bashrc (临时生效) ------>使用source和.是同一个指令
  3. . ~/.bashrc (临时生效)

iii)对所有用户都生效的方式

修改/etc/environment

sudo vim /etc/environment

直接把想添加的路径,添加原有的路径后面

让配置文件生效:

  1. 重启(永久生效)
  2. source /etc/environment (临时生效) ------>使用source和.是同一个指令
  3. . /etc/environment (临时生效)

iv)对所有用户生效

修改/etc/bash.bashrc

sudo vim /etc/bash.bashrc 
使用export表达式,将路径添加到最后

让配置文件生效:

  1. 重启(永久生效)
  2. source /etc/bash.bashrc (临时生效) ------>使用source和.是同一个指令
  3. . /etc/bash.bashrc (临时生效)

四、shell中的变量

shell本身是擅长运行指令,shell是一个弱数据类型的语言

【1】定义变量

C中:
存储类型 数据类型 变量名;

shell中:
变量=变量的值       ----->如果变量的值中间没有空格直接使用
变量='变量的值'     ----->变量的值中间有空格
变量="变量的值"     ----->使用一个已有的变量给新的变量赋值,并且赋值中有空格时
''内,$变量名,不会被展开

注意:

  1. shell中等号两侧不允许有空格
  2. 如果有空格会把变量名识别成一个指令

【2】使用变量

在shell中如果使用变量的值,需要给变量名前加$
$变量名    ${变量名}

【3】变量的赋值

1、使用已有的变量给新的变量赋值
var1=hello
var2=world
var3="$var1 $var2"

shell脚本的本质:命令的集合

五、shell中的数组

【1】定义

C中
int arr[4]={1,2,3,4};

shell:
数组名=(1 2 3 4)    ----->每个元素之间以空格作为分隔

shell中支持稀疏数组
数组名=([下标]=初始值1 [下标]=初始值2 ·····)

#!/bin/bash
arr=(12 90 89 100)   

#shell中支持稀疏数组,下标不连续的数组
brr=([0]=90  [3]=70  [7]=900)

crr[0]=29   #给crr数组中下标为0的元素赋值
crr[3]=78   #给crr数组中下标为3的元素赋值 

#再重新给brr中没有提供的下标的元素赋值
brr[4]=67

echo ${brr[4]}
echo ${crr[3]}

【2】数组中元素的访问 

${数组名[下标]}

访问数组中的所有元素
${数组名[*]}
${数组名[@]}

${#数组名[*]}
#!/bin/bash
arr=(12 90 89 100)   

#shell中支持稀疏数组,下标不连续的数组
brr=([0]=,2  [3]=70  [7]=900)

crr[0]=29   #给crr数组中下标为0的元素赋值
crr[3]=78   #给crr数组中下标为3的元素赋值 

#再重新给brr中没有提供的下标的元素赋值
brr[4]=67

echo ${brr[@]}
echo ${crr[*]}
echo ${#brr[*]}     #4 对于稀疏数组,#会记录数组中实际元素的个数

echo ${#brr[0]}     #2 对数组中的指定元素使用#,#记录元素中字符的个数

练习:

1、定义一个数组,使用外部参数给数组赋值,通过数组求外部参数的个数

2、把家目录的下的所有文件名放到数组中,并记录家目录下文件的个数

#!/bin/bash
arr=($*)    #把所有的外部参数赋值给数组arr
echo ${#arr[*]}


arr2=(`ls ~`)   #把家目录的所有文件名赋值给数组arr1
echo ${#arr2[*]}
echo ${arr2[@]}

 【3】使用已有的数组给新的数组赋值

#!/bin/bash
arr1=(1 2 3 4)
arr2=(b n m l)

#定义一个数组arr3,使用原来的arr1和arr2给新数组arr3赋值
arr3=(${arr1[*]} ${arr2[*]})
echo ${arr3[@]}   # 1 2 3 4 b n m l
arr3=(${arr1[*]}${arr2[*]})
echo ${arr3[@]}  #1 2 3 4b n m l
echo ${#arr3[*]}

六、shell中的输入输出

【1】输出--->echo

echo默认不解析转义字符并且会自动换行

-e:让echo指令解析转义字符

-n:取消换行

#!/bin/bash
echo "111\n"     #echo默认不解析转义字符,会默认换行
echo -e "111\n"  #111 换行两次
echo "111\n" -e  #111\n -e  echo的参数不能放在最后一个位置,被识别成字符串
echo -ne "111\n" #让echo取消换行,-n参数

 【2】read

read  变量名  
read -s 变量名    ---->输入的内容不回显
read -p "提示信息" 变量名   ----->-p回显提示信息
read -n 字符个数  变量名    ----->控制输入的字符个数,当超过会自动停止
read -t 秒数 变量名         ----->控制读入数据的时间,如果指定时间内不输入会自动停止
read -a 数组名    ---->输入数组

练习:

1、尝试把read除了-a以外的参数结合起来使用

#!/bin/bash
#read -p "请输入一个变量"  var
#read -n 3 var
#read -t 3 var
#read -a arr
read -sp "请输入一个变量" -n 3 -t 4 var
#echo ${#arr[*]}
echo $var

七、shell中的算术运算

shell本身不擅长算术运算,需要借助于运算符和其他指令

(())     $[]    let    expr

【1】(())

常用于shell中整数的算术运算

(())几乎支持所有的C语言语法,支持shell中的幂运算 **

使用方法:

  1. ((表达式1,表达式2,表达式3,····))每一个表达式都会执行,取到最后一个表达式的结果
  2. (())内使用变量时,可以加$也可以不加$
  3. (())内的运算符两侧,可以有空格也可以没有空格
  4. 变量名=$((表达式)),获取(())的运算结果
  5. 可以直接在(())内进行赋值操作,((var1 = var1+var2))

练习:

1、终端输入两个三位数,将其中一个自增,把两个变量赋值给第二个变量相加并输出

#!/bin/bash
read -p "请输入两个变量" var1 var2   #如果同一行获取两个变量,变量中间放空格
((var1++))   #自增
((var2=var1+var2))
echo $var1
echo $var2
((var1=var1**3))     #对var1进行幂运算
echo $var1

 2、求root用户的uid和ubuntu/linux用户gid相加的结果,比较这两个数的大小关系

#!/bin/bash
num1=`id -u root`
num2=`id -g`
echo $((num1+num2))
#比较num1和num2的大小关系
echo $((num1<num2))
#比较num1和num2的大小关系
echo $((num1<num2?num2:num1))

【2】$[]实现算数运算

使用方法: (仍然支持幂运算和自增自减运算)

  1. 变量名=$[表达式1,表达式2,表达式3,····],每一个表达式都执行,获取最后一个表达式的结果
  2. 运算时,运算符两侧可以有空格也可以没有空格
  3. 使用变量时,可以加$也可以不加$
  4. $[]本质上会遗留一个计算结果在,运算所在行,可以选择直接echo $[表达式] ,变量名=$[表达式]
#!/bin/bash
num1=100
num2=30
echo $[num1+num2]   #直接在终端回显130
echo $[num1++,num2**2,++num2]  #31
echo $num1   #101
echo $num2   #31

练习:

1、计算当前目录下文件个数和家目录下文件个数的总和

2、计算家目录下.c和.sh文件的和

#!/bin/bash
arr=(`ls`)
arr1=(`ls ~`)
brr=(`ls` `ls ~`)  #把两个路径下的文件,放到同一个数组中 
crr=(${arr[*]} ${arr1[*]})   #先把两个路径下的文件分别存在不同数组中,再拼接两个数组
num1=${#arr[*]}
num2=${#arr1[*]}
echo $[num1+num2]
echo ${#brr[*]}
echo ${#crr[*]}


arr3=(`ls ~/*.c`)
arr4=(`ls ~/*.sh`)
#对前两行的数组计数
num3=${#arr3[*]}
num4=${#arr4[*]}
echo $[num3+num4]

【3】let实现算数运算

使用方法:

  1. let 变量名=表达式 ----->let和变量名中间一定有空格
  2. let使用变量可以加$,也可以不加$
  3. let运算时,运算符两侧一定不能有空格
  4. let 表达式,运算是可以进行的但是没有办法接收运算的结果

 

#!/bin/bash
num1=100
num2=30
let ret=num2**2  #支持幂运算
let num1++    #支持自增运算,但是不能接收表达式的结果
echo $ret
echo $num1   #101
 

【4】expr

expr是一条指令

使用方法:

  1. expr使用变量的值时,必须加$
  2. 运算符两侧必须加空格 (不支持幂运算和自增自减运算)
  3. expr在使用时,一些字符需要转义,*,>,
  4. expr直接回显指令的执行结果到终端

ARG1 | ARG2
     如果ARG1的值不为0,结果就是ARG1,否则就是ARG2

ARG1 & ARG2
     如果RAG1和ARG2都不为0,结果是ARG1,否则是0

ARG1 < ARG2
     ARG1 is less than ARG2

ARG1 <= ARG2
     ARG1 is less than or equal to ARG2

ARG1 = ARG2
     ARG1 is equal to ARG2

ARG1 != ARG2
     ARG1 is unequal to ARG2

ARG1 >= ARG2
      ARG1 is greater than or equal to ARG2

ARG1 > ARG2
      ARG1 is greater than ARG2

#!/bin/bash
num1=-2
num2=9
: 'expr $num1 + $num2
expr $num1 - $num2
expr $num1 / $num2
expr $num1 % $num2
expr $num1 \* $num2
'
num3=0
expr $num1 \| $num2
expr $num1 \& $num2
expr $num2 \> $num1
expr $num2 != $num1
expr $num2 = $num1

练习:

1、终端读入两个数据,使用expr比较大小关系

2、计算/etc/group中,第20行组用户gid和第10行组用户gid的和

#!/bin/bash
read -p "请输入两个变量" var1 var2
expr $var1 \>= $var2

#获取/etc/group中第20行用户的gid
num1=`head -20 /etc/group | tail -1 | cut -d : -f 3`
#获取/etc/group中第10行用户的gid
num2=$(head -10 /etc/group | tail -1 | cut -d : -f 3)
expr $num1 + $num2

 expr对字符串的运算

match str1  str2
    返回str2在str1中完全匹配的个数(str2可以作为str1中子串)        

substr STRING POS LENGTH
    如果字符串长度不够截取长度,就把字符串中所有的内容都截取出来
    从string中的第pos个位置开始截取长度为length的子串(pos从1开始)
index STRING CHARS
    返回字符在字符串中第一次出现的位置,如果是多个字符,返回最先在字符串中出现的字符的下标
    (下标从1开始)
length STRING
    求字符串的长度
#!/bin/bash
str1=hello
str2=hl
expr match $str1 $str2  #0,因为hello中不能匹配到hl字符串
expr substr $str1 2 3   #pos计数从1开始
expr index $str1 lo     #3l在hello最先出现
expr length $str1
expr length $str2

练习:

1、终端输入网址,如:www.baidu.com,要求:

接触网址每个部分,并放入数组中,不能使用cut,使用expr解决

#!/bin/bash
read -p "请输入一个网址" net
len=`expr length $net`    #网址的长度
#找第一个.的位置
pos1=`expr index $net .`
#截取第一个.前面的所有子串
arr[0]=`expr substr $net 1 $((pos1-1))`

#为了找第二个.需要把后面的所有子串都截取出来
str2=`expr substr $net $((pos1+1))  $len`

#找到第二个.的位置
pos2=`expr index $str2 .`
arr[1]=`expr substr $str2 1 $((pos2-1))`

arr[2]=`expr substr $str2 $((pos2+1)) $len`
echo ${arr[*]}

八、shell中的分支语句

【1】if···else分支

[]就是test指令
#单分支结构
if [ test语句 ]    -----> if  test 表达式 
then
    语句块
fi

#双分支
if [ test语句 ]    -----> if  test 表达式 
then
    语句块
else 
    条件不成立执行的语句块
fi

#多分支语句
if [ test语句 ]    -----> if  test 表达式 
then
    语句块
elif [ test语句 ]   ------> elif test 表达式 
then
    条件不成立执行的语句块
fi

#!/bin/bash
num1=90
num2=300
#if [ $num1 -le $num2 ]
if test $num1 -le $num2
then
    echo "num1<=num2"
fi

余下见链接

 https://blog.csdn.net/ck0056/article/details/132816564

练习:

写一个1.sh脚本,将以下内容放到脚本中:

在家目录下创建目录文件,dir

在dir下创建dir1和dir2

把当前目录下的所有文件拷贝到dir1中,

把当前目录下的所有脚本文件拷贝到dir2中

把dir2打包并压缩为dir2.tar.xz

再把dir2.tar.xz移动到dir1中

解压dir1中的压缩包

使用tree工具,查看dir下的文件

#!/bin/bash
mkdir ~/dir
mkdir ~/dir/dir2 ~/dir/dir1
cp * ~/dir/dir1/ -r
cp *.sh ~/dir/dir2/
tar -cJf ~/dir/dir2.tar.xz ~/dir/dir2/
mv ~/dir/dir2.tar.xz ~/dir/dir1/
tar -xvf ~/dir/dir1/dir2.tar.xz
tree ~/dir

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

ck钉钉钉

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

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

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

打赏作者

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

抵扣说明:

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

余额充值