• Day 58 shell脚本命令


    1.概念:

    Shell linux 中一个重要的层次,它是用户与系统交互作用的界面。在介绍 linux 命令时, shell 都作为命令解释程序出现:它接收用户打入的命令,进行分析,创建子进程实现命令所规定的功能,等子进程终止工作后,发出提示符。这是 shell 最常见的使用方式。
    Shell 除了作为命令解释程序以外,还是一种高级程序设计语言, 它有变量,关键字,有各种控制语句,如 if case while for 等语句,有自己的语法结构 。利用 shell 程序设计语言可以编写出功能很强、但 代码简单的程序,特别是它把相关的 linux 命令有机地组合在一起,可大大提高编程的效率,充分利用 linux 系统的开放性能,设计出适合自己要求的命令。
    2.简单的脚本:
    脚本文件后缀为.sh,创建和打开用vim命令。第一行为
    #!/bin/bash

    后面可将Linux中的命令加上去,最终的结果和在终端输入一致。

    下面是一个简单的shell脚本示例:

    1. #!/bin/bash
    2. #This is to show what a example looks like
    3. date
    4. echo "Our first example."
    5. echo #this inserts an empty line in output .
    6. echo "We are currently in the following diractory."
    7. echo
    8. /bin/pwd
    9. echo
    10. echo "This diractory contains following files"
    11. /bin/ls
    Shell 脚本中用 # 表示注释,相当于 C 语言的 // 注释。但如果 # 位于第一行开头,并且是 #! ( 称为 Shebang)则例外,它表示该脚本使用后面指定的解释器 /bin/sh 解释执行。如果把这个脚本文件加上可执行权限然 后执行 :,执行方式如下:
    user02@vir:~$ chmod a+x test.sh
    user02@vir:~$ ./test.sh #方法一
    user02@vir:~$ . test.sh #方法二
    user02@vir:~$ source test.sh #方法三
    更改权限则使用chmod命令。
    3.shell语法:
    数据类型只有字符串
    Shell 变量名通常是以 字母或下划线打头的字母、数字和下划线字符序列,并且大小写字母意义不同 。有两种类型的 Shel l变量:环境变量和临时变量
    环境变量:
    环境变量可以从父进程传给子进程,因此 Shell 进程的环境变量可以从当前 Shell 进程传给 fork 出来的子进程。用 printenv 命令可以显示当前 Shell 进程的环境变量。
    临时变量:
    只存在于当前 Shell 进程,用 set 命令可以显示当前 Shell 进程中定义的所有变量 (包括临时变量和环境变 环境变量是任何进程都有的概念,而临时变量是 Shell 特有的概念。在 Shell 中,环境变量和临时变量的定义和用法相似。在 Shell 中定义或赋值一个变量 量) 和函数:
    user02$ VARNAME=HELLO #定义一个临时变量
    user02$ export VARNAME=HELLO #定义一个环境变量
    user02$ env | grep VARNAME #env能查到就是环境变量,查不到就是临时变量
    user02$ unset VARNAME #取消环境变量
    文件名代换:
    这些用于匹配的字符称为通配符 (wildcard), : * ? [ ] 具体如下 :
    * :匹配 0 个或多个任意字符
    ? :匹配一个任意字符
    [ 若干字符 ] : 匹配方括号中任意一个字符的次出现一次的文件名
    命令代换:
    “ ' ” 反引号括起来的也是一条命令, Shell 先执行该命令,然后将输出结果立刻代换到当前命令行中。例如 . 定义一个变量存放 date 命令的输出:
    user02$ DATE=`date`
    user02$ echo=$DATE #$变量名:变量的值
    命令代换也可以用 S() 表示 :
    user02$ DATE=$(date)
    算数代换:
    使用 $(()) ,用于算术计算, (()) 中的 Shell 变量取值将转换成整数,同样含义的 $[ ] 等价例如 :
    user02$ VAR=45
    user02$ echo $(($VAR+3)) # 等价 $((VAR+3)) $[VAR+3]
    S(())) 中只能用 +-*/ () 运算符,并且只能做整数运算
    S[base#n], 其中 base 表示进制, n 按照 base 进制解释,后面再有运算数,按十进制解释
    user02$ echo $[2#10+3] # 二进制 10 ,然后+ 3
    user02$ echo $[8#10+3] # 八进制 10 ,然后 +3
    转义字符:
    C 语言类似, \ Shell 中被用作转义字符,用于去除紧跟其后的单个字符的特殊意义 ( 回车除外 ) ,换句话说,紧跟其后的字符取字面值。例如 :
    user02$ echo \$PATH
    user02$ \\
    创建文件 --test
    touch --test # 报错
    单引号:
    Shell 脚本中的单引号和双引号一样都是字符串的界定符,而不是字符的界定符。单引号用于保持引号内所有字符的字面值,即使引号内的 \ 和回车也不例外,但是字符串中不能出现单引号。如果引号没有配对 就输入回车, Shell 会给出续行提示符,要求用户把引号配上对。例如 :
    user02$ echo "abcde"
    user02$ echo 'abcd'
    双引号:
    被双引号括住的内容,将被视为单一字串。它防止通配符扩展,但允许变量扩展。单引号不能展开变量。
    user02$ VAR=`date`
    user02$ echo "$VAR"
    2022 09 17 日星期六 10:22:52 CST
    user02$ echo "${VAR}"
    2022 09 17 日星期六 10:22:52 CST
    user02$ echo 'VAR'
    user02$ echo '${VAR}'
    4.脚本语法:
    条件测试:
    命令 test [ 可以测试一个条件是否成立,如果测试结果为真,则该命令的 Exit Status 0 ,如果测试结果为假,则命令的 Exit Status 1 。例如测试两个数的大小关系 :
    user02$ VAR=2
    user02$ test $var -gt 1
    user02$ echo $?
    常见的测试命令如下表所示 :
    [ -d DIR ]如果DIR存在并且是一个目录则为真
    [ -f FILE ]如果FILE存在且是一个普通文件则为真
    [ -z STRING ]如果STRING的长度为零则为真
    [ -n STRING ]如果STRING的长度非零则为真
    [ STRING1 = STRING2 ]如果两个字符串相同则为真
    [ STRING1 != STRING2 ]如果字符串不相同则为真
    [ ARG1 OP ARG2 ] ARG1和ARG2应该是整数或者取值为整数的变量,op是-eq (等于) -ne (不等于) -lt (小于) -le (小于等于) -gt (大于) -ge (大于等于)之中的一个。
    C 语言类似,测试条件之间还可以做与、或、非逻辑运算 :
    [ ! EXPR ] EXPR 可以是上表中的任意一种测试条件, ! 表示 逻辑反 ( )”
    [ EXPR1 -a EXPR2 ] EXPR1和EXPR2可以是上表中的任意一种测试条件,-a表示“逻辑与”
    [ EXPR1 -o EXPR2 ] EXPR1和EXPR2可以是上表中的任意一种测试条件,-o表示“逻辑或”
    示例如下所示:
    $ VAR=abc
    $ [ -d user02 -a $VAR = 'abc' ]
    $ echo $?
    4.分支:
    if/then/elif/fi:
    C 语言类似,在 Shell 中用 if then elif else fi 这几条命令实现分支控制。这种流程控制语句本质上也是由若干条 Shell 命令组成的
    if [ -f ~/.bashrc ] ; then
    . ~/.bashrc
    fi
    其实是三条命令, if [ -f ~/.bashrc ] 是第一条, then . ~/.bashrc 是第二条, fi 是第三条。如果两条命
    令写在同一行则需要用 == == 号隔开,一行只写一条命令就不需要写 == == 号了,另外, then 后面有换行,但这条命令没写完, Shell 会自动续行,把下一行接在 then 后面当作一条命令处理。和 [ 命令一 样,要注意命令和各参数之间必须用空格隔开。 if 命令的参数组成一条子命令,如果该子命令的 Exit Status 0 ( 表示真 ) ,则执行 then 后面的子命令,如果 Exit Status 0 ( 表示假 ) ,则执行 elif else 或者 fi 后面的子命令。 if 后面的子命令通常是测试命令,但也可以是其它命令。
    fi 表示 if 语句块的结束。见下例 :
    1. #! /bin/bash
    2. if [ -f test.c ];then
    3. echo "test.c is a file"
    4. else
    5. echo "test.c is not a file"
    6. fi
    “== : ==” 是一个特殊的命令,称为空命令,该命令不做任何事,但 Exit Status 总是真。
    1. echo "Is it morning? Please answer yes or no. "
    2. read YES_OR_NO
    3. if [ "$YES_OR_NO" = "yes" ]; then
    4. echo "Good morning!"
    5. elif [ "$YES_OR_NO" = "no" ]; then
    6. echo "Good afternoon!"
    7. else
    8. echo "Sorry, $YES_OR_NO not recognized. Enter yes or no."
    9. return ;
    10. fi
    上例中的 read 命令的作用是等待用户输入一行字符串,将该字符串存到一个 Shell 变中。
    此外, Shell 还提供了 && || 语法,和 C 语言类似,具有 Short-circuit 特性,很多 Shell 脚本喜欢写成这样 :
    test "$(whoami)" != 'root' && (echo you are using a non-privileged account;)
    && 相当于 “if...then..." || 相当于 “if not...then..."
    && || 用于连接两个命令,而上面讲的 -a -o 仅用于在测试表达式中连接两个测试条件,要注意它们的区别,例如 :
    test "$VAR" -gt 1 -a "$VAR" -lt 3
    示例如下:
    1. #! /bin/bash
    2. echo "请输入你要判别的文件名: "
    3. read file_ name
    4. if [ -f "$file_ name" ]; then
    5. echo 'it is a file
    6. elif [ -d "$file_ nane" ]; then
    7. echo 'It is a dir'
    8. elif [ -p $file_ _name ] ; then
    9. echo 'It is pipe
    10. else
    11. echo 'it is not a known file'
    12. exit 1
    13. fi
    case/esac:
    case 命令可类比 C 语言的 switch/case 语句, esac 表示 case 语句块的结束。 C 语言的 case 只能匹配整型或字符型常量表达式,而 Shell 脚本的 case 可以匹配字符串和 Wildcard , 每个匹配分支可以有若干条命令, 末尾必须以 ;; 结束 ,执行时找到第一个匹配的分支并执行相应的命令,然后直接跳到 esac 之后,不需要 C 语言一样用 break 跳出
    示例如下:
    1. #! /bin/bash
    2. echo "Is it morning? Please answer yes or no."
    3. read YES_OR_NO
    4. case "$YES_OR_NO" in
    5. yes|y|Yes|YES)
    6. echo "Good Morning!";;
    7. [nN][oO])
    8. echo "Good Afternoon!";;
    9. *)
    10. echo "Sorry, $YES_OR_NO not recognized. Enter yes or no."
    11. return 1;;
    12. esac

  • 相关阅读:
    超声波清洗机好用吗?哪家超声波清洗机好?不错超声波清洗机推荐
    java 使用bc库封装ASN1结构案例
    小程序制作(超详解!!!)第十三节 随机数求和
    Java实用的DateUtils时间工具类介绍
    Discourse 在 2022-11 的最新版本中提供了新的边栏
    TikTok Shop商品的评价有哪些规则?
    ping github.com 显示 Request timeout for icmp_seq 0 问题
    设计模式-单例模式
    Vue3 - watchEffect 使用教程
    C#的基于.net framework的Dll模块编程(四) - 编程手把手系列文章
  • 原文地址:https://blog.csdn.net/m0_60247706/article/details/127656727