• Linux Shell 基础语法 流程控制 逻辑运算 字符串操作详细解析


    1 shell 简单入门

    Shell是一个用C语言编写的程序,它是用户使用linux的桥梁。Shell既是一种命令语言,又是一种程序设计语言。
    Shell是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。
    本文主要以shell脚本为重心展开介绍。

    哈喽,大家好,我是[有勇气的牛排](全网同名)🐮🐮🐮

    有问题的小伙伴欢迎在文末[评论,点赞、收藏]是对我最大的支持!!!。

    https://www.couragesteak.com/article/347

    1.1 shell分类

    Linux shell的种类有很多,目前流行的 Shell 包括 ash、bash、ksh、csh、zsh…,用户可以通过查看/etc/shells文件中的内容查看自己主机中当前有哪些种类的shell。

    [root@master shell]# cat /etc/shells
    /bin/sh
    /bin/bash
    /sbin/nologin
    /usr/bin/sh
    /usr/bin/bash
    /usr/sbin/nologin
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    查看当前linux正在使用的shell类型

    echo $SHELL
    
    • 1

    $SHELL:是一个环境变量,它记录了Linux当前用户所使用的的shell类型。

    1.2 shell脚本

    1、编写规范

    vim test.sh

    #!/bin/bash
    
    # 这是一个注释
    
    echo "Hello World"
    
    • 1
    • 2
    • 3
    • 4
    • 5

    #!:是约定标记,告诉系统这个标记需要什么解释器,即需要哪种shell

    2、文件命名规则:以 .sh 结尾。

    3、执行
    shell 脚本是一种解释执行的程序,可以在终端直接调用(需要使用chmod命令赋予脚本执行权限)

    chmod +x ./test.sh
    
    • 1

    4、打印当前进程

    #!/bin/bash
    
    echo $$    # 输出当前进程PID
    
    echo "Hello World"
    
    • 1
    • 2
    • 3
    • 4
    • 5

    1.3 Shell 脚本四种启动方式

    分为如下四种:

    1、bash xxx.sh

    • 启动一个bash子进程,运行脚本中的命令

    2、./xxx.sh

    以脚本的第一行注释为标准

    #!/bin/bash:启动一个bash子进程脚本
    #!/bin/python:执行一个pyhton脚本

    3、source xxx.sh. xxx.sh

    在本进程运行这一个脚本,和上面的区别在于会对本进程造成影响

    2 shell 变量

    在Bash shell中,每个变量都是字符串。

    2.1 普通变量

    2.1.1 定义变量
    variable=value
    variable='value'
    variable="value"
    
    • 1
    • 2
    • 3

    注意:=周围不能有空格

    #!/bin/bash
    
    url=www.couragesteak.com
    echo $url
    
    name='有勇气的牛排'
    echo $name
    
    author="导演"
    echo $author
    
    # {} 可以帮助识别变量边界
    echo "I am ${name}."
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    输出:

    www.couragesteak.com
    有勇气的牛排
    导演
    I am 有勇气的牛排.
    
    • 1
    • 2
    • 3
    • 4
    2.1.2 变量中单引号、双引号的区别
    #!/bin/bash
    
    url=www.couragesteak.com
    
    webUrl1='有勇气的牛排官网:${url}'
    webUrl2="有勇气的牛排官网:${url}"
    
    echo $webUrl1
    echo $webUrl2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    单引号' ':被单引号包围时,单引号里面是什么就输出什么。

    双引号" ":双引号会解析里面的变量和命令,而不是原样输出。

    2.1.3 将命令的结果赋值给变量

    语法

    variable=`command`	# 不推荐,易混淆
    variable=$(command)
    
    • 1
    • 2

    实例:

    vim log.txt
    
    你真棒
    
    • 1
    • 2
    • 3
    [root@master shell]# log=$(cat log.txt)
    [root@master shell]# echo $log
    你真棒
    
    • 1
    • 2
    • 3
    2.1.4 只读变量 readonly

    使用 readonly命令可以将变量定义为只读变量,其值不可改变

    #!/bin/bash
    
    url=www.couragesteak.com
    readonly url 
    
    url="ccc"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    输出

    [root@master shell]# ./test.sh
    ./test.sh: line 6: url: readonly variable
    
    • 1
    • 2
    2.1.5 删除变量

    语法:unset 变量名

    2.2 环境变量

    2.2.1 环境变量与删除
    # 使用export声明
    export name="有勇气的牛排"
    echo $name
    
    • 1
    • 2
    • 3
    # 删除环境变量name
    unset name
    
    • 1
    • 2
    2.2.2 查看环境变量

    查看指定环境变量

    env | grep name
    
    • 1

    查看系统所有环境变量

    env
    
    • 1

    2.3 特殊变量

    变量描述
    $0当前脚本文件名
    $#传递给脚本或函数测参数个数
    $*传递给脚本或函数的所有参数
    $@传递给脚本或函数的所有参数。但被双引号包含是与@、*稍有不同
    $?上个名利的退出状态,或函数的返回值
    $$当前Shell进程ID

    2.4 位置参数

    位置参数变量描述
    $nn为数字,$0表示当前Shell脚本程序的名称,$1-9代表第一道第九个参数,十以上的参数需要用大括号包含,如 {10}
    $*这个变量代表命令行中所有的参数,$把所有的参数看成一个整体
    $@这个变量也代表命令行中的所有参数,不过$@把每个参数区分对待
    $#这个变量代表命令行中的所有参数的个数
    2.4.1 使用脚本文件传递位置参数

    语法:./脚本.sh <参数1> <参数2> ...

    实例:

    ./test.sh charles 有勇气的牛排
    
    • 1
    #!/bin/bash
    
    echo "参数1: $1"
    echo "参数2: $2"
    
    • 1
    • 2
    • 3
    • 4

    image.png

    2.4.2 使用函数传递位置参数
    ./test.sh
    
    • 1
    #!/bin/bash
    
    # 定义函数
    function func(){
        echo "参数1:$1"
        echo "参数2:$2"
    }
    
    # 调用函数
    func charles 有勇气的牛排
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    输出同上一个案例

    2.5 键盘输入

    read: usage: 
    read [-ers] [-a array] [-d delim] [-i text] [-n nchars] [-N nchars] [-p prompt] [-t timeout] [-u fd] [name ...]
    
    • 1
    • 2

    -a:后面跟一个变量,多个变量,按顺序赋值
    -p:输出提示信息
    -t:秒数,等待时间(s)
    -n:数字,只接受指定长度字符,就会执行
    -s:隐藏输入的数据,适合密码等敏感信息
    -d:结束标志
    -e:在输入的时候可以使用补全功能。

    实例:可补全,输入名字

    read -e -p "请输入您的姓名:" -a name
    
    • 1

    image.png

    3 运算符

    3.1 算数运算符

    原生bash不支持数学运算,不过可以通过其他命令辅助实现。

    实例:计算两数之和

    #!/bin/bash
    
    res=`expr 1 + 1`在这里插入代码片`
    echo "结果:${res}"
    
    echo '1+1='`expr 1 + 1`
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    3.2 逻辑运算符

    运算符描述
    -a
    -o
    !

    3.3 字符串运算符

    运算符描述举例
    =判断2个字符串是否相等[ $a=$b ]
    !=判断2个字符串是否不相等[ $a!=$b ]
    -z判断字符串长度是否为0[ -z $a ]
    -n判断字符串是否不为0[ -n $a ]
    str判断字符串是否为空[ $a ]

    3.4 文件测试运算符

    文件测试运算符主要用于 Linux/Unix 文件的各种属性

    操作符描述
    -b判断文件是否为 块设备 文件
    -c判断文件是否为 字符设备 文件
    -d判断文件是否是 目录
    -f判断文件是否为 普通文件
    -g判断文件是否设置了 SGID 位
    -k判断文件是否设置了 粘贴位(Sticky Bit) (可理解为防删除位)
    -p判断文件是否有管道
    -u判断文案是否设置了 SUID位
    -r判断文件是否可读
    -w判断文件是否可写
    -x判断文件是否可执行
    -s检测文件是否为空(文件大小是否>0)
    -e检测文件(包括目录)是否存在

    用法如:[ -b $file ]

    1、判断目录是否存在

    # 判断目录是否存在
    FILE=/usr/local
    if [ -d "$FILE" ]; then
        echo "$FILE 存在"
    else
        echo "$FILE 不存在"
    fi
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    2、判断文件是否存在

    FILE=/usr/local/test/yy.txt
    if [ -f "$FILE" ]; then
        echo "$FILE 存在"
    else
        echo "$FILE 不存在"
    fi
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    4 流程控制

    4.1 if 语句

    4.1.1 if-else:判断相等
    #!/bin/bash
    
    read a
    read b
    
    if(($a == $b))
    then
        echo 'a=b'
    else
        echo 'a!=b'
    fi
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    4.1.2 if-elif-else:成绩段位判断
    #!/bin/bash
    
    read -p "请输入您的分数:" score
    
    if(($score < 60));then
        echo "未及格"
    elif (($score >= 60 && $score < 85));then
        echo "还不错"
    else
        echo "优秀"
    fi
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    4.1.3 判断字符串是否为空
    ifname=
    if [ ! -n "$name" ]; then
         echo 字符串为空
    else:
         ehco 字符串包含内容
    fi
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    4.2 case条件语句

    实例:根据数字判断今天是星期几

    #!/bin/bash
    
    printf "星期转换\n"
    
    read -p "请输入今天是一周的第几天:" num
    
    case $num in
        1)
            echo "周一"
            ;;
        2)
            echo "周二"
            ;;
        3)
            echo "周三"
            ;;
        4)
            echo "周四"
            ;;
        5)
            echo "周五"
            ;;
        6)
            echo "周六"
            ;;
        7)
            echo "周天"
            ;;
    esac
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    4.3 循环

    4.3.1 for 循环

    实例:计算1加到n的和

    #!/bin/bash
    
    printf "计算1~n数字之和\n"
    read -p "请输入n:" n
    
    for ((i=1;i<=${n};i++))
    do
        ((sum += i)) 
    done
    
    echo "结果为:$sum"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    image.png

    4.3.2 while循环

    实例:计算1加到n的和

    #!/bin/bash
    
    printf "计算1~n数字之和\n"
    read -p "请输入n:" n
    
    i=0
    while ((i <= n)) 
    do
        ((sum += i)) 
        ((i++))
    done
    
    echo "结果为:$sum"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    4.3.3 until 循环

    定义:想判断是否添加是否成立,若成立则进入循环,反之不进入。

    #!/bin/bash
    
    printf "计算1~n数字之和\n"
    read -p "请输入n:" n
    
    i=0
    until ((i>n))
    do
        ((sum += i)) 
        ((i++))
    done
    
    echo "结果为:$sum"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    4.4 流程控制语句

    4.4.1 exit

    在系统中,用于退出当前用户登录状态

    在Shell脚本中,用户退出当前脚本

    exit [返回值]
    
    • 1
    4.4.2 break语句

    定义:跳出当前循环

    4.4.3 continue 语句

    定义:跳过本次循环,继续下一次循环

    4.5 函数定义

    语法

    function 函数名 () {
    	程序
    }
    
    • 1
    • 2
    • 3

    实例

    #!/bin/bash
    
    function getName(){
        printf "name:Charles\n"
    }
    
    getName
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    实例2

    #!/bin/sh
    
    function getProcessPid() {
        String="charles"
        echo 777    
        echo $String
    
        return 666 
    }
    
    echo ---
    name=$(getProcessPid)
    echo 返回值为:$name
    
    getProcessPid
    echo 返回值为:$?
    
    ---输出
    返回值为:777 charles
    777
    charles
    返回值为:154
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    5 字符串操作

    5.1 获取字符串长度

    语法:${#您的字符串}

    #!/bin/bash
    
    name="有勇气的牛排"
    echo "${name}的长度为:${#name}"
    
    • 1
    • 2
    • 3
    • 4

    5.2 字符串拼接

    #!/bin/bash
    
    nick="有勇气的牛排"
    obj="博客"
    
    # 连续拼接
    str1=$nick$obj  
    
    # 中间加内容
    str2="$nick $obj"
    str3=$nick":"$obj
    
    # 不规则拼接
    str4="这里是${nick}的${obj}"
    
    echo $str1
    echo $str2
    echo $str3
    echo $str4
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    image.png

    5.3 字符串截取

    5.3.1 从左边开始

    语法:${string : start : length}

    #!/bin/bash
    
    str="abcdefgh"
    echo ${str:2:3}
    
    • 1
    • 2
    • 3
    • 4

    输出:cde

    5.3.2 从右边开始

    语法:${strint : 0-start : length}

    #!/bin/bash
    
    str="abcdefgh"
    echo ${str:0-2:3}
    
    • 1
    • 2
    • 3
    • 4

    输出:gh

    有点奇怪,以后在测试

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

    语法:${string#*chars},星号表示通配符,也可以写其他内容。

    #!/bin/bash
    
    url="https://www.couragesteak.com/"
    echo ${url#*//}
    
    • 1
    • 2
    • 3
    • 4

    输出:www.couragesteak.com/

    5.3.4 使用 % 截取左边字符
    #!/bin/bash
    
    url="https://www.couragesteak.com/index.html"
    
    echo ${url%/*}
    # 输出:https://www.couragesteak.com
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    6 数组

    在shell中,通过()来表示数组,数组元组之间用空格

    #!/bin/bash
    
    # 不要求类型完全相同
    arr=(1 2 "有勇气的牛排")
    
    # 后去数组中所有元素
    echo ${arr[*]}
    echo ${arr[@]}
    
    # 根据下标获取, 起始为0
    echo ${arr[2]}
    
    # 数组长度不固定
    arr[6]=3
    echo ${arr[*]}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    image.png

  • 相关阅读:
    UG NX二次开发(C#)-UI Styler-批量选择点
    java计算机毕业设计ssm民宿管理系统设计7lky4(附源码、数据库)
    毕昇编译器优化:Lazy Code Motion
    springboot结合elasticJob
    react native 安卓打包报这个错误> Task :app:mergeDexRelease
    【面试专题】设计模式篇①
    38.企业快速开发平台Spring Cloud+Spring Boot+Mybatis之Highcharts 使用百分比的堆叠柱形图
    Socket通信之网络协议基本原理
    ‘face_alignment‘ has no attribute ‘FaceAlignment‘
    基于改进灰狼优化算法的边缘计算任务调度方法
  • 原文地址:https://blog.csdn.net/zx77588023/article/details/126603744