这是我参与8月更文挑战的第2天,活动详情查看: 8月更文挑战

Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁。Shell 既是一种命令语言,又是一种程序设计语言。
Shell 是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。 在计算机科学中,Shell俗称壳(用来区别于核),是指“为使用者提供操作界面”的软件(command interpreter,命令解析器)。
Linux shell属于一种图形化shell界面,并且shell脚本指的是运行在shell上的脚本。

二.基础入门

1.基础语法格式与标准

自定义shell脚本通常被放于/usr/local/sbin目录下,这样方便标准统一,shell脚本通常以sh结尾,比如test.sh

#! /bin/bash
## 这是第一个shell
echo 'Hello world!'

其中,第一行#! /bin/bash必须要有,#! 是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种 Shell(这里用的是bash)。
echo用于向窗口输出文本,文本用单引号括起来,执行结果如下:

[root@VM-12-14-centos sbin]# sh test.sh 
Wed Aug  4 11:00:46 CST 2021
Hello,word!
test.sh
  • #!/bin/bash 指定脚本要使用的 Shell 类型为 Bash 。
  • #! 被称为 Sha-bang ,或者 Shebang , Linux 会分析它之后的指令,并载入该指令作为解析器。
  • ls 就是脚本文件的内容了,表明我们执行 hello.sh 脚本时会列举出当前目录的文件列表并且会向控制台打印 hello world
  • shell脚本的执行方式常用的有两种:

  • 如果为非Root用户,可以给脚本添加执行权限(因为vim编辑默认不带执行权限)
  • chmod +x test.sh #给此脚本test.sh添加执行权限
  • ./test.sh #执行当前目录下的脚本
  • sh test.sh 直接执行
  • 也可以使用sh -x test.sh 显示执行过程,方便排查脚本错误

    shell中常用的date命令
    date "+%Y-%m-%d %H:%M:%S" 2021-08-01 12:25:10
    date -d "+1 day" "%Y-%m-%d" 加一天
    date -d "-1 year" "%Y-%m-%d" 减一年

    (1)基本运算符与参数赋值

  • $[ ] : 加减乘除,不必添加空格
  • $(( )) :加减乘除等,不必添加空格
  • #! /bin/bash
    sum=$[$a+$b]
    echo "12345+$sum"
    echo "------------"
    echo "第一个数:"
    read  x
    echo ”第二个数:
    read y
    sum=$[$x+$y]
    echo "这是两个数的和:$sum"
    

    执行结果如下:

    [root@VM-12-14-centos sbin]# sh test.sh 
    2021-08-04 11:44:42
    Hello,word!
    test.sh
    12345+3
    ------------
    第一个数:
    ”第二个数:
    这是两个数的和:1998
    

    read x/a/b/c/d 还可以替换为read -p “字符串” x/a/b/c/d

    read -p "当前结果满意吗:y/N" x
    

    read -p相当于echo的效果上进行输入

    (2)条件判断语句

    基本条件判定符号如下:

  • 条件在(( ))双括号中使用,可用 参数名 + >= ,<=,>,<,=
  • 条件在[ ]方括号中使用,使用 -lt (小于),-gt (大于),-le (小于等于),-ge (大于等于),-eq (等于),-ne (不等于)。
  • [] : 中括号旁边和运算符两边必须添加空格 (可以使用,不推荐)
  • [[ ]]:中括号旁边和运算符两边必须添加空格 (字符串验证时,推荐使用)
  • (()) : 中括号旁边和运算符两边必须添加空格 (数字验证时,推荐使用)
  • [[]] 和 (()) 分别是[ ]的针对数学比较表达式和字符串表达式的加强版。
  • 使用[[ … ]]条件判断结构,而不是[ … ],能够防止脚本中的许多逻辑错误。比如,&&、||、<和> 操作符能够正常存在于[[ ]]条件判断结构中,但是如果出现在[ ]结构中的话,会报错。比如可以直接使用if [[ a != 1 && a != 2 ]], 如果不适用双括号, 则为if [ a -ne 1] && [ a != 2 ]或者if [ ane1aa -ne 1 -a
  • [[ ]]中增加模式匹配特效;
  • (( ))不需要再将表达式里面的大小于符号转义,除了可以使用标准的数学运算符外,还增加了以下符号
  • 【1】if

    #! /bin/bash
    read -p "请输入你的成绩:" a
    if ((a>=60));then
    	echo "你的成绩及格了,恭喜你!"
    

    【2】if else

    #! /bin/bash
    read -p "请输入你的成绩:" a
    if ((a>=60));then
    	echo "你的成绩及格了,恭喜你!"
       echo "你的成绩没及格,下次加油!"
    

    【3】if elif else

    #!/bin/bash
    read -p "请输入你的成绩:" a
    if ((a>=60)) && ((a<=90));then
       echo "你的成绩及格了,恭喜你!"
    elif ((a>90));then
       echo "你的成绩非常优秀!"
       echo "你的成绩没及格,下次加油!"
    运行结果图如下

    【4】case语句

    #!/bin/bash
    read -p "请输入你想判断的整数:" x
    a=$[$x%2]
    case $a in
            echo "这是一个奇数!"
            echo "这是一个偶数!"
    

    Shell case语句为多选择语句。可以用case语句匹配一个值与一个模式,如果匹配成功,执行相匹配的命令。 case需要一个esac(就是case反过来)作为结束标记,每个case分支用右圆括号,用两个分号表示break,其中“;;”不是跳出循环,是不在去匹配下面的模式

  • break :跳出总循环
  • continue:跳出当前循环,继续下一次循环
  • case脚本常用于编写系统服务的启动脚本。

    【5】while

    #条件循环
    while condition
        command
    #无限循环
    while :
        command
    

    【6】until循环

    until 循环执行一系列命令直至条件为 true 时停止。 until 循环与 while 循环在处理方式上刚好相反。

    until condition
        command
    

    【7】for循环

    for 变量名 in 循环的条件; do command

    #!/bin/bash
    for i in `seq 1 5`;do
            echo $i
    

    seq 1 5 代表1到5的一个序列

    (3)输出语句

    【1】echo

    仅建议用于字符串的输出 echo " " 或者echo ' '

    【2】printf

    printf 不会像 echo 自动添加换行符,我们可以手动添加 \n 无大括号,直接以空格分隔

  • 格式:printf format-string [arguments...] 其中(format-string: 格式控制字符串、arguments: 参数列表)
  • 案例:printf "%-10s %-8s %-4.2f\n" 郭靖 男 66.1234
  • %s %c %d %f 都是格式替代符:

  • d:Decimal 十进制整数 对应位置参数必须是十进制整数,否则报错!
  • s:String 字符串 对应位置参数必须是字符串或者字符型 否则报错
  • c:Char 字符 对应位置参数必须是字符串或者字符型 否则报错
  • f:Float 浮点 对应位置参数必须是数字型 否则报错
  • %-10s : 指一个宽度为10个字符(-表示左对齐,没有则表示右对齐),任何字符都会被显示在10个字符宽的字符内,如果不足则自动以空格填充,超过也会将内容全部显示出来。
  • %-4.2f :指格式化为小数,宽度为4个字符,其中.2指保留2位小数。
  • \a :警告字符,通常为ASCII的BEL字符
  • \b :后退
  • \c :抑制(不显示)输出结果中任何结尾的换行字符(只在%b格式指示符控制下的参数字符串中有效),而且,任何留在参数里的字符、任何接下来的参数以及任何留在格式字符串中的字符,都被忽略
  • \f :换页(formfeed)
  • \n :换行
  • \r :回车(Carriage return)
  • \t :水平制表符
  • \v :垂直制表符
  • \ :一个字面上的反斜杠字符
  • \ddd :表示1到3位数八进制值的字符。仅在格式字符串中有效
  • \0ddd :表示1到3位的八进制值字符
  • (4)shell脚本中的函数

    函数建议写在开头,函数永远要在调用之前, 使用$1来代表第一个参数,便于按顺序传参 可以在脚本内调用方法,也可以在脚本外调用方法

    #!/bin/bash
    function add(){
            sum=$[$1 + $2]
            return $sum
    add 1 2
    echo "当前和为:$? !"
    #!/bin/bash
    function add(){
            sum=$[$1 + $2]
            return $sum
    add $1 $2
    echo "当前和为:$? !"
    
    sh hanshu.sh 3 6
    

    当前和为:9 !

    (5)常用文件操作

    shell 脚本中if还经常判断关于档案属性,比如判断是普通文件还是目录,判断文件是否有读写执行权限等。常用的也就几个选项:

  • -e :判断文件或目录是否存在
  • -d :判断是不是目录,并是否存在
  • -f :判断是否是普通文件,并存在
  • -r :判断文档是否有读权限
  • -w :判断是否有写权限
  • -x :判断是否可执行 使用if判断时,具体格式为: if [ -e filename ] ; then
  • 三.实战入门

    1.入门练手

    (1)1-100的和

    #!/bin/bash
    sum=0
    while (($a<=100))
            sum=$[$a+$sum]
            a=$[$b+$a]
    echo $sum 
    

    (2)输入一个数,求从1-n的和

    #bin/bash
    sum=0
    read -p "请输入一个数字:" a
    while ((a<1))
            read -p "输入的数字格式不正确,请重新输入一个数字:" a
    for i in `seq 1 $a`;do
            sum=$[$i+$sum]
    echo $sum
    

    (3)拷贝一个目录到另一个目录下

    shell脚本对文件目录的判定

    shell 脚本中if还经常判断关于档案属性,比如判断是普通文件还是目录,判断文件是否有读写执行权限等。常用的也就几个选项:
    -e :判断文件或目录是否存在
    -d :判断是不是目录,并是否存在
    -f :判断是否是普通文件,并存在
    -r :判断文档是否有读权限
    -w :判断是否有写权限
    -x :判断是否可执行
    使用if判断时,具体格式为: if [ -e filename ] ; then
    #!/bin/bash
    cd /home/xt
    list=`ls`
    for i in ${list[0]}
            echo "$i"
            if [ -d $i ];then
               echo "123456"
               cp -r $i /home/test1/
    或者********************************
    #! /bin/bash
    for f in `ls /root/`; do
    	if [ -d $f ] ; then
    		cp -r $f /tmp/
    

    2.文件信息处理

    awk处理文件

    #!/bin/bash
    awk -F "," '{print NF,$1,$2,$3,$4,$5,$6,$7}' a.txt
    awk -F "," '{print NF,$0}' a.txt
    直接读取文件,输出第123457列的数据
    $0直接输出所有的数据,

    3.实用脚本

    (1)开启/关闭Tomcat

    sh tomcat.sh start/stop
    开启tomcat,并进入tomcat的日志
    关闭tomcat,并判断是否要杀死僵尸进程,删除webapps下的war包

    #!/bin/bash
    tomcat_home=/home/xt/test-tomcat
    STARTTOMCAT=$tomcat_home/bin/startup.sh
    SHUTDOWN=$tomcat_home/bin/shutdown.sh
    WEB=$tomcat_home/webapps
    MYLOG=/applog/ossDown-downBatch
    TOMCATLOG=$tomcat_home/logs
    case $1 in
    start)
            echo "启动Tomcat!"
            $STARTTOMCAT
            cd $TOMCATLOG
            tail -f catalina.out -n 500
    stop)
            echo "关闭Tomcat!"
            $SHUTDOWN
            pid=`ps -ef |grep test-tomcat |grep -v "grep"|awk '{print $2}'`
            if [ "$pid" = "" ];then
                    echo "当前tomcat线程已停止"
                    echo "关闭的进程号为: $pid"
                    kill -9 $pid
            cd $WEB
            rm -rf *
           
    粉丝