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

【Linux】shell脚本编程

目录

概念:

shell脚本的本质:

shell脚本编程:

shell变量:

变量的定义格式:

变量的分类

自定义变量:

环境变量:

命令变量与命令行参数:

预定义变量:

shell中的语句

功能性语句

read(类似c当中 scanf)

expr

let

test

字符串测试

整数测试

文件属性测试

结构性语句

if...then...fi

基本结构

分层结构

嵌套结构

elif(多路分支结构)

case语句

for循环

for语句的几种书写格式

while循环

循环控制语句

数组

定义数组

获取数组

数组切片

gcc编译步骤


 

概念:

shell脚本的本质:

shell命令的有序集合

shell既是应用程序又是脚本语言,并且是解释型语言,不需要编译,解释一条执行一条。

shell脚本编程:

将shell命令结合一些按照一定逻辑集合到一起,写一个 .sh文件,实现一个或多个功能,这个脚本不用编译直接执行

创建shell脚本文件的步骤:

1. 创建一个脚本文件
    touch xxx.sh
2. 将脚本文件的权限修改为可执行
    chmod 777 xxx.sh
3. 编辑脚本内容
    vi xxx.sh
4. 执行脚本文件
    ./xxx.sh   或   bash xxx.sh

练习:

1)在当前路径下创建file_1到file_5, 5个普通文件

2)删除 file_2和file_3文件(使用通配符)

3)将剩下的file文件用tar压缩成bz2的格式

4)将压缩文件复制到家目录下

5)进入到家目录解压压缩文件

6)删除压缩包

touch file_{1..5}
rm file_[23]
tar -cvjf file.tar.bz2 file_[^23]
cp file.tar.bz2 ~
cd ~
tar -xvf file.tar.bz2 
rm file.tar.bz2

shell变量:

shell中允许建立变量存储数据,但是不支持数据类型

(如:整型、字符、浮点类型),所有赋值给变量的值都解释为一串字符

变量的定义格式:

变量名=值

注:等号两边不能有空格

取shell变量的值:$变量名

变量的分类

自定义变量:

YY=hello      # YY="hello world"

echo $YY

XX=$YY   --->  将 YY 的值赋值给 XX

echo $XX

unset 变量名    ---> 取消该变量的值

环境变量:

系统配置好的、内置变量

使用命令查看系统环境变量: printenv或 env

export 变量名=值 临时终端有效

永久生效只需要将这个命令放到用户目录下 .bashrc 文件中,当前用户永久有效。

若放到 /etc/bash.bashrc 这个文件中所有用户永久有效

命令变量与命令行参数:

$0 执行的脚本名

$1-$9、${10}-${n} 命令行空格传的参数 n:第几个命令行参数

$# 命令行参数个数除 $0

$@$* 遍历输出命令行参数内容

预定义变量:

$? 获取的是上一个命令是否是正确的执行结果

0:真 非0:假

$$ 获取当前shell的进程 PID

shell中的语句

1) 说明性语句

以 #开始到该行结束,不被解释执行

#!/bin/bash告诉操作系统使用哪种类型的shell执行此脚本文件

2) 功能性语句

任意的shell命令、用户程序或其他的shell程序

3) 结构性语句

条件测试语句、多路分支语句、循环语句、循环控制语句

功能性语句

read(类似c当中 scanf)

从终端获取值赋值给变量

格式:read 变量名1 变量名2...

加提示语句:read-p"提示字符串"变量名1 变量名2 ...

注:把终端读入空格隔开的第一个单词赋值给第一个变量,第二个单词赋值给第二个变量,依次类推赋值,剩余所有单词赋值给最后一个变量。

expr

算术运算命令expr 主要用于进行简单的整数运算,包括(+)、减(-)、乘(*)、整除(/)、求模(%)等操作

注意:

1) 运算符左右两侧必须有空格

2) *和()必须加转义字符,\*、\( \)

3) expr语句可以直接输出运算结果

如:expr \( 12 + 3 \) \* 2

NUM=`expr \( 12 + 3 \) \* 2`:将运算结果赋值给变量

read -p "要输入的值" val1 val2 val3
expr \( $val1 + $val2 \) \* $val3

let

在运算中不能有空格

运算结果需要赋值给一个变量

变量参与运算的过程不用加 $ 取值

test

test 语句可以测试三种对象

字符串 整数 文件属性

字符串测试
s1 = s2        测试两个字符串的内容是否一样
    test "hello" = "world"
    echo $?    # 1        相等为真,不相等为假
    
s1 != s2        测试字符串的内容是否有差异
    test "hello" != "hello"
    echo $?    # 1        相等为假,不相等为真
    
-z s1           测试s1字符串长度是否为0
    test -z "" 
    echo $?    # 0        字符串长度为0
    test -z "hello"
    echo $?    # 1        字符串长度不为0
    
-n s1            测试s1字符串长度是否不为空  (空的时候为1,反之为0)
    test -n ""
    echo $?    # 1        字符串长度为空,则为假
    test -n "hello"
    echo $?    # 0        字符串有长度为真
整数测试
a -eq b        测试a和b是否相等的  # equal
    read A B
    test $A -eq $B
    echo $?    # 如果两个数相等则为真,反之为假

a -ne b        测试 a 和 b是否不相等 # no equal
    read A B
    test $A -ne $B
    echo $?    # 如果两个数不相等则为真,反之为假
    
a -gt b        测试 a 是否大于 b  # greater than
    read A B
    test $A -gt $B
    echo $?    # 如果a大于b则为真,反之为假

a -ge b        测试 a 是否大于等于 b  # greater equal than
    read A B
    test $A -ge $B
    echo $?    # 如果a大于等b则为真,反之为假
    
a -lt b        测试 a 是否小于 b  # less than
    read A B
    test $A -lt $B
    echo $?    # 如果a小于b则为真,反之为假
    
a -le b        测试 a 是否小于等于 b  # less eqaul than
    read A B
    test $A -le $B
    echo $?    # 如果a小于等于b则为真,反之为假
文件属性测试
-d name        测试name是否为一个目录
    test -d 路径
    echo $?    # 如果name是目录则为真,反之为假

-f name        测试name是否为一个普通文件
    test -f 路径
    echo $?    # 如果name是普通文件则为真,反之为假
    
-e name        测试文件是否存在
    test -e 路径
    echo $?    # 如果文件或目录存在则为真,反之为假

结构性语句

if...then...fi

基本结构
if 表达式
then
    命令表
fi

分层结构
if 表达式
then
    命令表1
else
    命令表2
fi

嵌套结构
if 表达式1
then
    if 表达式2
    then
        命令表 2
    else
        命令表3
    fi
else
    命令表
fi

elif(多路分支结构)

if 表达式1
then
    命令表1
elif 表达式2
then
    命令表2
elif 表达式3
then
    命令表3
...
else
    表达式 n
fi


注意:
	如果表达式为真, 则执行命令表中的命令; 否则退出if语句, 即执行fi后面的语句。 
	if和fi是条件语句的语句括号, 必须成对使用;
	命令表中的命令可以是一条, 也可以是若干条。

补充操作符:

! 非运算 例如 [ ! false ] 返回 true

&& 逻辑与 例如 [[ $a -lt 100 && $b -gt 100 ]] 返回 false

|| 逻辑或 例如 [[ $a -lt 100 || $b -gt 100 ]] 返回 true

case语句

格式:

case 变量 in
模式1)
    命令表1
    ;;
模式2)
    命令表2
    ;;
*)
    命令表n
    ;;
esac

工作方式:
    取值后面必须为关键字 in ,每一个模式必须以右括号结束。
    取值可以为变量或者常量,取值检测匹配的每一个模式
    一旦模式匹配,其间所有命令开始执行直至 ;;
    执行完匹配模式相应的命令不会再继续匹配其他的模式
    如果无一匹配模式,使用 * 号捕获该值

| 或者 ; 转换模式

学生成绩管理系统,用shell中的case实现

90-100:A

80-89:B

70-79:C

60-69:D

<60:不及格

for循环
格式:
for 变量名 in 单词表
do
    命令表
done

执行顺序:
变量依次取单词表中的各个单词,  每取一次单词, 就执行一次循环体中的命令.  循环次数由单词表中的单词数确定. 命令表中的命令可以是一条, 也可以是由分号或换行符分开的多条

for I in 1 2 3 4 5 6 7 8 9 10
do
    echo "$I"
done
for语句的几种书写格式
变量I从单词表中取值
1) for I in 1 2 3 4 5 6 7 8 9 10 do ... done

变量I从 1-10个数中取值
2) for I in {1..10} do ... done

变量I从命令行取值,省略in、单词表
3) for I do ... done
   ./脚本名 1 2 3 4 5

书写格式类似C语言
4) for (( i = 0; i < 10; i++ )) do ... done
for (( i = 0; i < 10; i++ ))
do
    echo "$i"
done
while循环
格式:
while 命令或表达式
do
    命令表
done

执行顺序:
while语句首先测试其后的命令或表达式的值,如果为真,就执行一次循环体中的命令,然后再测试该命令或表达式的值,执行循环体,直到该命令或表达式为假时退出循环。

I=1
while [ $I -lt 10 ]
do
    echo $I
    (( I++ ))
done

echo $(( I++ ))
循环控制语句

breakn:结束n层循环

continuen:跳过n层本次循环,继续下一个循环

for (( i = 0; i < 10; i++ ))
do
    for (( j = 0; j < 10; j++ ))
    do
        if [ $j -eq 3 ]
        then
            # continue
            # continue 2
            # break
            break 2
        fi
        echo "$i:$j"
    done
done

数组

定义数组

在shell当中,用小括号 ( ) 来表示数组,数组元素之间用空格来隔开

1. 数组名=(value1 value2 value3 ...)

2. 数组名=(

value1

value2

...

)

3. 通过键值对的形式赋值

数组名=([0]=value1 [1]=value2)

4. 通过分别定义数组变量的方式来定义

数组名[0]="value1"

数组名[1]="value2"

5. 列表名="value0value1 value2"

数组名=($列表名)

注意:

1. 数组中的元素,必须以空格来隔开

2. 定义数组以其索引,可以不按顺序来定义的 如:数组名=([0]=value0 [1]=value2 [8]=array)

3. 字符串是数组中最重要的数据类型,可以通过 ($str) 转成数组

获取数组

1. 获取单个数组元素

${数组名[下标]}

2. 获取数组全部内容

${数组名[@]}或 ${数组名[*]}

3. 获取数组元素的个数

${#数组名[@]} 或 ${#数组名[*]}

数组切片

取数组中的某一段的元素的值

格式:

${数组名[@或*]:起始位置:长度}

gcc编译步骤

预处理:处理以#开头的内容,展开头文件、替换宏定义、删除注释,但是不会进行语法检查。
gcc -E xxx.c -o xxx.i

编译:进行语法检查,将.i文件转化成.s汇编文件
gcc -S xxx.i -o xxx.s

汇编:将汇编文件转化成二进制文件(不可执行)
gcc -c xxx.s -o xxx.o

链接:链接库文件,将不可执行的二进制文件转化成可执行的二进制
gcc xxx.o -o xxx

写 Makefile 时一般这样写
gcc xxx.o -o xxx
gcc -c xxx.c -o xxx.o


http://www.kler.cn/a/473053.html

相关文章:

  • [Git] git cherry-pick
  • USB 驱动开发 --- Gadget 设备连接 Windows 免驱
  • 【cuda学习日记】2.2 使用2维网络(grid)和2维块(block)对矩阵进行求和
  • STM32供电参考设计
  • 力扣刷题:数组OJ篇(下)
  • nginx-灰度发布策略(基于cookie)
  • 详解opencv resize之INTER_LINEAR和INTER_AREA
  • 用户注册模块(芒果头条项目进度4)
  • JVM三JVM虚拟机
  • 战地雷达通信系统中无人机与特种车辆智能组网及雷达通信一体化研究报告
  • UE蓝图节点备忘录
  • C++ 泛型编程:动态数据类模版类内定义、类外实现
  • 嵌入式系统 (2.嵌入式硬件系统基础)
  • 文献阅读分享:ChatGPT在推荐系统中的偏见研究
  • 使用Qt实现json数据的格式检测并序列化输出 Qt5.4.0环境
  • 根据docker file 编译镜像
  • 入门嵌入式(六)——定时器
  • GPIO输入及两个应用案例
  • 『SQLite』解释执行(Explain)
  • benchANT 性能榜单技术解读 Part 1:写入吞吐
  • 金融租赁系统助力行业转型与升级的创新之路
  • 生成模型:变分自编码器-VAE
  • 产品经理-商业模式构建 - AxureMost
  • SparkStreaming集群调优
  • H2数据库在单元测试中的应用
  • 实时数仓:Apache Iceberg 的表管理与实时数仓架构设计