• shell脚本介绍


    • 本文章主要介绍下shell脚本相关的一些语法

    1 变量

    • 在shell中,使用变量之前通常并不需要事先为它们做出声明,一般是使用时才创建。默认情况下,所有变量都被看作字符串来存储。通过在变量前加一个$符号来访问它的内容。
    lng@ubuntu:~/myshell$ myData=hello
    lng@ubuntu:~/myshell$ echo $myData
    hello
    lng@ubuntu:~/myshell$ 
    
    • 1
    • 2
    • 3
    • 4
    • 如果要赋值的字符串中有空格,就要用引号括起来,并且注意,等号两边不能有空格
    lng@ubuntu:~/myshell$ myData="hello word"
    lng@ubuntu:~/myshell$ echo $myData
    hello word
    lng@ubuntu:~/myshell$ 
    
    • 1
    • 2
    • 3
    • 4
    • 如果你把一个$变量表达式放在双引号中,程序执行到这一行时就会把变量替换为它的值,如果把它放到单引号中,就不会发生替换现象。
    lng@ubuntu:~/myshell$ myData="welcome to xian"
    lng@ubuntu:~/myshell$ 
    lng@ubuntu:~/myshell$ echo "$myData"
    welcome to xian
    lng@ubuntu:~/myshell$ echo '$myData'
    $myData
    lng@ubuntu:~/myshell$ 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    环境变量

    • 当一个shell脚本程序开始执行时,一些变量会根据环境设置中的值进行初始化。这些变量通过用大写字母作名字,以便把它们和用户在脚本程序里定义的变量区分开。
      • $HOME : 当前用户的家目录
      • $PATH : 以冒号分隔的用来搜索命令的目录列表
      • $0 : shell脚本的名字。相当于main函数的argv[0]
      • $# : 传递给脚本的参数个数。相当于main函数的 argc - 1
      • $$ : shell脚本的进程号
    lng@ubuntu:~/myshell$ echo $HOME
    /home/lng
    lng@ubuntu:~/myshell$ echo $PATH
    /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
    lng@ubuntu:~/myshell$ 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    lng@ubuntu:~/myshell$ cat myTest.sh 
    #! /bin/sh
    echo $0
    echo $#
    echo $$
    lng@ubuntu:~/myshell$ ./myTest.sh 
    ./myTest.sh
    0
    4053
    lng@ubuntu:~/myshell$ ./myTest.sh aa bb cc
    ./myTest.sh
    3
    4054
    lng@ubuntu:~/myshell$ 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    参数变量

    • 如果脚本程序在调用时带有参数,一些额外的变量就会被创建。
      • $1, $2, … : 脚本程序的参数。相当于main函数的argv[1],argv[2],…
      • $@: 参数列表
      • $* : 参数列表
    lng@ubuntu:~/myshell$ cat myTest.sh 
    #! /bin/sh
    echo $1
    echo $2
    echo $3
    echo $@
    echo $*
    lng@ubuntu:~/myshell$ ./myTest.sh aaa 111 fff
    aaa
    111
    fff
    aaa 111 fff
    aaa 111 fff
    lng@ubuntu:~/myshell$ 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    2 条件

    test 或 [ 命令

    • test命令可以使用的条件类型可以归为三类:字符串比较,算数比较和文件有关的测试
    • 字符串比较
    字符串比较结果
    string1 = string2如果两个字符串相同则结果为真
    string1 != string2如果两个字符串不同则结果为真
    -n string如果字符串不为空则结果为真
    -z string如果字符串为null则结果为真
    • 算术比较
    算术比较结果
    expression1 -eq expression2如果两个表达式相等则结果为真
    expression1 -ne expression2如果两个表达式不等则结果为真
    expression1 -gt expression2如果expression1大于expression2则结果为真
    expression1 -ge expression2如果expression1大于等于expression2则结果为真
    expression1 -lt expression2如果expression1小于等于expression2则结果为真
    expression1 -le expression2如果expression1小于等于expression2则结果为真
    ! expression如果表达式为假则结果为真
    • 文件条件测试
    文件条件测试结果
    -d file如果文件是一个目录则结果为真
    -f file如果文件是一个普通文件则结果为真
    -r file如果文件可读则结果为真
    -w file如果文件可写则结果为真
    -x file如果文件可执行则结果为真
    -s file如果文件大小不为0则结果为真
    • 测试案例
    lng@ubuntu:~/myshell$ cat myTest.sh 
    #! /bin/sh
    
    str="hello"
    
    if [ $str = "hello" ];then
    	echo "str = hello"
    fi
    
    lng@ubuntu:~/myshell$ ./myTest.sh 
    str = hello
    lng@ubuntu:~/myshell$ 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    lng@ubuntu:~/myshell$ cat myTest.sh 
    #! /bin/sh
    
    num1=100
    num2=200
    if [ $num1 -eq $num2 ]
    then
    	echo "num1 eq num2"
    else
    	echo "num1 no eq num2"
    fi
    
    
    lng@ubuntu:~/myshell$ ./myTest.sh 
    num1 no eq num2
    lng@ubuntu:~/myshell$ 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    lng@ubuntu:~/myshell$ ls
    a.txt  b.txt  dire  myTest.sh
    lng@ubuntu:~/myshell$ cat myTest.sh 
    #! /bin/sh
    if test -f a.txt;then
    	echo "a.txt is file"
    fi
    
    if [ -f b.txt ];then
    	echo "b.txt is file"
    fi
    
    if [ -d dire ];then
    	echo "dire is directory"
    fi
    lng@ubuntu:~/myshell$ ./myTest.sh 
    a.txt is file
    b.txt is file
    dire is directory
    lng@ubuntu:~/myshell$ 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    3 控制结构

    3.1 if语句

    • if语句非常简单:它对某个命令的执行结果进行测试,然后根据测试结果有条件地执行一组语句。
    • 语法结构
    if condition
    then
    	statements
    else
    	statements
    fi
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 测试用例
    lng@ubuntu:~/myshell$ cat myTest.sh 
    #! /bin/sh
    
    echo "please input yes or no!"
    
    #读取终端输入
    read temp
    
    if [ $temp = "yes" ]
    then
    	echo "you input is yes"
    else
    	echo "you input is no"
    fi
    
    
    lng@ubuntu:~/myshell$ ./myTest.sh 
    please input yes or no!
    yes
    you input is yes
    lng@ubuntu:~/myshell$ 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    3.2 elif

    • 语法结构
    if condition1
    then
    	statements
    elif condition2
    then
    	statements	
    else
    	statements
    fi
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 测试案例
    lng@ubuntu:~/myshell$ cat myTest.sh 
    #! /bin/sh
    
    echo "please input yes or no!"
    
    #读取终端输入
    read temp
    
    if [ $temp = "yes" ]
    then
    	echo "you input is yes"
    elif [ $temp = "no" ]
    then
    	echo "you input is no"
    else
    	echo "you input unknow"
    fi
    
    
    lng@ubuntu:~/myshell$ ./myTest.sh 
    please input yes or no!
    fff
    you input unknow
    lng@ubuntu:~/myshell$ 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    3.3 for语句

    • 我们可以用for结果来循环处理一组值,这组值可以是任意字符串的集合。
    • 语法结构
    for variable in values
    do
    	statements
    done
    
    • 1
    • 2
    • 3
    • 4
    • 测试案例
    lng@ubuntu:~/myshell$ cat myTest.sh 
    #! /bin/sh
    
    for fruit in apple bnana pear;
    do
    	echo "I like $fruit"
    done
    
    
    lng@ubuntu:~/myshell$ ./myTest.sh 
    I like apple
    I like bnana
    I like pear
    lng@ubuntu:~/myshell$ 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    3.4 while语句

    • for循环特别适合对于一系列字符串进行循环处理,但如果事先不知道循环次数,就可以用while
    • 语法结构
    while condition; do
    	statements
    done
    
    • 1
    • 2
    • 3
    • 测试案例
    lng@ubuntu:~/myshell$ cat myTest.sh 
    #! /bin/sh
    
    
    echo "please input password!"
    
    read pwd
    
    while [ "$pwd" != "admin" ];do
    	echo "Sorry, try again"
    	read pwd
    done 
    exit 0
    lng@ubuntu:~/myshell$ ./myTest.sh 
    please input password!
    123456
    Sorry, try again
    000
    Sorry, try again
    admin
    lng@ubuntu:~/myshell$ 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    3.5 case

    • 每条匹配分支可以有若干条命令,末尾必须以 ; ; 结束
    • 语法结构
    case variable in
    	pattern [ | pattern ] ...) statements;;
    	pattern [ | pattern ] ...) statements;;
    	...
    esac
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 测试用例
    lng@ubuntu:~/myshell$ cat myTest.sh 
    #! /bin/sh
    
    echo "please input num"
    read buf
    
    case "$buf" in
    	one) echo "input is one";;
    	two) echo "input is two";;
    	three) echo "input is three";;
    	four) echo "inpuit is four";;
    esac
    
    lng@ubuntu:~/myshell$ ./myTest.sh 
    please input num
    three
    input is three
    lng@ubuntu:~/myshell$ 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    lng@ubuntu:~/myshell$ cat myTest.sh 
    #! /bin/sh
    
    echo "please input yes or no"
    read buf
    
    case "$buf" in
    	yes|y|YES|Y) echo "input is yes";;
    	n*|N*) echo "input is no";;
    esac
    
    lng@ubuntu:~/myshell$ ./myTest.sh 
    please input yes or no
    y
    input is yes
    lng@ubuntu:~/myshell$ ./myTest.sh 
    please input yes or no
    noo
    input is no
    lng@ubuntu:~/myshell$ 
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    4 函数

    • 如果需要编写大型的shell脚本程序,就要用到函数
    • 一个简单的函数
    lng@ubuntu:~/myshell$ cat myTest.sh 
    #! /bin/sh
    
    myFunc(){
    	echo "this is myFunc"
    }
    
    echo "------"
    myFunc
    echo "++++++"
    lng@ubuntu:~/myshell$ ./myTest.sh 
    ------
    this is myFunc
    ++++++
    lng@ubuntu:~/myshell$ 
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 函数传入参数
    lng@ubuntu:~/myshell$ cat myTest.sh 
    #! /bin/sh
    
    myFunc(){
    	echo "param num is $#"
    	echo "param 1 is $1, param 2 is $2"
    	echo "this is myFunc"
    }
    
    echo "------"
    myFunc aaa bbb
    echo "++++++"
    lng@ubuntu:~/myshell$ ./myTest.sh 
    ------
    param num is 2
    param 1 is aaa, param 2 is bbb
    this is myFunc
    ++++++
    lng@ubuntu:~/myshell$ 
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    5 命令

    5.1 break

    • 跳出循环,跟C语言用法一样

    5.2 continue

    • 跳出本次循环,跟C语言用法一样

    5.3 echo

    • 打印命令

    5.4 exit n

    • exit命令使脚本程序以推出码n结束运行
    • 在shell脚本编程中,推出码0表示成功,退出码1~125是脚本程序可以使用的错误代码。其余数字具有保留含义。
    退出码说明
    126文件不可执行
    127命令未找到
    128及以上出现一个信号

    5.5 set

    • 为shell设置参数变量

    5.6 uset

    • 从环境中删除变量或者函数
    lng@ubuntu:~/myshell$ myData="hello"
    lng@ubuntu:~/myshell$ echo $myData
    hello
    lng@ubuntu:~/myshell$ unset myData
    lng@ubuntu:~/myshell$ echo $myData
    
    lng@ubuntu:~/myshell$ 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    5.7 find

    • find命令可用于文件的查找。介绍下常用的文件查找的命令

    5.7.1 根据文件名查找

    • find 查找的目录 -name 文件名
    lng@ubuntu:~/share/test$ ls
    evp_aes.cpp  evp_aes.h  evp_aes.o  main.cpp  main.o  makefile  res
    lng@ubuntu:~/share/test$ find ~ -name main.o
    /home/lng/share/getopt/main.o
    /home/lng/share/test/main.o
    lng@ubuntu:~/share/test$ 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    5.7.2 根据文件大小查找

    • find 查找的目录 -size 文件大小
    lng@ubuntu:~/share/test$ ls -la
    total 92
    drwxr-xr-x  2 lng lng  4096 Aug 28  2021 .
    drwxrwxr-x 15 lng lng  4096 Apr 30 05:18 ..
    -rwxr--r--  1 lng lng  3760 Jul 31  2021 evp_aes.cpp
    -rwxr--r--  1 lng lng  2115 Jul 31  2021 evp_aes.h
    -rw-rw-r--  1 lng lng 22312 Aug 28  2021 evp_aes.o
    -rwxr--r--  1 lng lng    57 Aug 28  2021 main.cpp
    -rw-rw-r--  1 lng lng 11904 Aug 28  2021 main.o
    -rwxr--r--  1 lng lng   203 Aug 28  2021 makefile
    -rwxrwxr-x  1 lng lng 32488 Aug 28  2021 res
    # 查找大于10k文件
    lng@ubuntu:~/share/test$ find ./ -size +10k
    ./res
    ./main.o
    ./evp_aes.o
    lng@ubuntu:~/share/test$ 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    5.7.3 根据文件类型查找

    • find 查找的目录 -type f/d/b/c/s/p/l
    lng@ubuntu:~/share/test$ ls
    evp_aes.cpp  evp_aes.h  evp_aes.o  main.cpp  main.o  makefile  res
    # 查找普通文件
    lng@ubuntu:~/share/test$ find ./ -type f
    ./main.cpp
    ./evp_aes.h
    ./evp_aes.cpp
    ./res
    ./main.o
    ./makefile
    ./evp_aes.o
    lng@ubuntu:~/share/test$ 
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
  • 相关阅读:
    【杂言】迟到的 2024 展望
    11. 一文快速学懂常用工具——网络工具(下)
    Word使用小技巧
    【38. 最长上升子序列】
    mybatis-plus集成分页插件,针对多数据源分页失效的问题
    基于FPGA的五段流水CPU设计
    LwIP笔记01:LwIP入门
    Netty——NIO(Selector)
    手机怎么修改编辑PDF中的文字?两分钟教你学会编辑方法
    论文阅读--通用对象检测中的遮挡处理研究综述
  • 原文地址:https://blog.csdn.net/new9232/article/details/127583599