zoukankan      html  css  js  c++  java
  • Linux下的shell编程(基础)

    一.Shell介绍shell是一个命令行解释器,脚本语言,活动在应用程序与内核之间,用于接收应用程序(用户)命令,调用操作系统内核。

    (1)编译型语言:

    程序在执行之前需要个专门的编译过程,把程序编译成为机器语言文件,运行时不需要重新翻译,直接使用编译的结果就行了。程序执行效率高,依养编译器,跨平台性差些。如C、C++、java

    (2)解释型语言:

    程序不需要编译,程序在运行时由解释器翻译成机器语言,每执行一次都要翻译一次。因此效率比较低。比如Python/javaScript/Shell等都是解释型语言。


     

    二、Shell解析器

    (1)Linux提供的Shell解析器有:

    [root@Linux01 home]#  cat /etc/shells
     /bin/sh    是bash的一个快捷方式 
     /bin/bash   bash是大多数Linux默认的shell,包含的功能几乎可以涵盖shell所有的功能
     /sbin/nologin  表示非交互,不能登录操作系统
     /bin/dash  小巧,高效,功能相比少一些
     /bin/tcsh  具有C语言风格的一种shell,具有许多特性,但是也有一些缺陷
      /bin/csh   是csh的增强版本,完全兼容csh

     

    (2)bash和sh的关系:

    [root@Linux01 bin]#  ll  | grep bash
    -rwxr-xr-x. 1 root root 942200 3月 23 2017 bash
    lrwxrwxrwx. 1 root root 4 6月 29 19:35 sh -> bash

    (3)Centos默认的解析器是bash

    [root@Linux01 bin]#  echo $SHELL
    /bin/bash


     

    三、Shell脚本入门

    一句话概括:简单来说脚本就是将需要执行的命令保存到文本中,按照顺序执行(由上往下执行),它是解释型的,不需要编译。

    1.脚本格式

    脚本以#!/bin/bash或者#!/bin/env bash开头(指定解析器)

    脚本中间写注释信息内容,单行注释#  多行注释 :<<EOF   EOF       注释内容如下

    <<EOF
    name:second-shell.sh
    desc:创建文件,在文件中添加内容,打印信息
    update:2020-07-02
    path:/home
    EOF

    然后写脚本内容

    2.第一个Shell脚本:输出helloworld

    (1)需求:创建一个Shell脚本,输出helloworld

    (2)案例实操:

    [jinghang@hadoop101 datas]$ touch helloworld.sh

    [jinghang@hadoop101 datas]$ vi helloworld.sh

     在helloworld.sh中输入如下内容

    #!/bin/bash

    echo "helloworld"

    运行脚本,会输出 helloWord

      3、脚本的常用执行方式

    第一种

    采用bash或sh+脚本的相对路径或绝对路径(不用赋予脚本+x权限)

           sh+脚本的相对路径

    [jinghang@hadoop101 datas]$ sh helloworld.sh

    Helloworld

           sh+脚本的绝对路径

    [jinghang@hadoop101 datas]$ sh /home/jinghang/datas/helloworld.sh

    helloworld

           bash+脚本的相对路径

    [jinghang@hadoop101 datas]$ bash helloworld.sh

    Helloworld

           bash+脚本的绝对路径

    [jinghang@hadoop101 datas]$ bash /home/jinghang/datas/helloworld.sh

    Helloworld

    第二种

    采用输入脚本的绝对路径或相对路径执行脚本(必须具有可执行权限+x,推荐采用这种方式)

    (a)首先要赋予helloworld.sh 脚本的+x权限

    [jinghang@hadoop101 datas]$ chmod +x helloworld.sh

    (b)执行脚本

    相对路径

    [jinghang@hadoop101 datas]$ ./helloworld.sh

    Helloworld

    绝对路径

    [jinghang@hadoop101 datas]$ /home/jinghang/datas/helloworld.sh

    Helloworld

    注意:第一种执行方法,本质是bash解析器帮你执行脚本,所以脚本本身不需要执行权限。第二种执行方法,本质是脚本需要自己执行,所以需要执行权限

    4、查看脚本的执行流程(一般使用这个命令来查看脚本执行的步骤)

    [jinghang@hadoop101 datas]$ bash -x  batch.sh

    5、查看脚本的语法(一般使用这个命令来检查脚本语法错误)

    [jinghang@hadoop101 datas]$ bash -n  batch.sh


     

    4、shell变量:变量是用来临时保存数据的,该数据是可以变化的数据

    1. 读取Shell中所有变量命令:set    读取环境变量:env
    2. 系统变量
      a)$HOME、$PWD、$SHELL、$USER
      b)读取变量:echo $变量名

    3. 自定义变量
      a)用户变量
          作用域(只在当前会话的当前用户下有效)
          定义变量:
              变量名=值
              变量名=`执行命令`
              变量名=$(执行命令)
          读取变量:echo $变量名
                echo ${A:2:3}  (切片,读取变量几位,索引从0开始,第一个冒号后面代表索引开始位置,第二个冒号后面代表读取几位)
                echo ${A}
                echo $A
          撤销变量:unset 变量名
          静态变量(一旦创建,只可读,不能unset): readonly 变量名=值
          定义有类型的变量
              目的:给变量做一些限制,固定变量的类型
              语法:declare 选项 变量名=变量值
              常用选项
                  -i 将变量看作整数
                  -r 创建只读变量
      b)全局环境变量
          作用域(针对于当前会话下的所有用户有效)
          关键字:export
          定义变量:export 变量名=值
          撤销和读取同上
      c)系统环境变量
          作用域(针对于所有会话下的所有用户都有效)
          编辑配置文件:vim /etc/profile
              例如添加系统环境变量 MYNAME=jinghang
                  #系统环境变量
                  export MYNAME=jinghang
         变量生效:source /etc/profile
             
         经验技巧:
          (1)变量名称可以由字母、数字和下划线组成,但是不能以数字开头,环境变量名建议大写。
          (2)等号两侧不能有空格
          (3)在bash中,变量默认类型都是字符串类型,无法直接进行数值运算。
          (4)变量的值如果有空格,需要使用双引号或单引号括起来。

    4. 特殊变量

                 a)$n
        语法:$n (功能描述:n为数字,$0代表该脚本名称,$1-$9代表第一到第九个参数,十以上的参数,十以上的参数需要用大括号包含,如${10})
         b)$#
        语法:$# (功能描述:获取所有输入参数个数,常用于循环)
         c)$*
        语法:$* (功能描述:这个变量代表命令行中所有的参数,$*把所有的参数看成一个整体)
         d)$@
        语法:$@ (功能描述:这个变量也代表命令行中所有的参数,不过$@把每个参数区分对待)
         e)$?
        语法:$? (功能描述:最后一次执行命令的返回状态。如果值为0,命令正确执行;如果值为非0(具体是哪个数,由命令自己来决定),则命令执行不正确)


    5、shell数组

    • 定义:

            Shell 数组用括号来表示,元素用"空格"符号分割开,如果元素中包含空格,则该元素使用双引号引起来,例如"hello word"

    • 语法:

            往数组里添加值,数组的长度自增,元素索引从0开始
              数组名=(value1 value2 value3)

    • 赋值:

            创建时添加 数组名=(A B "C B" D)
              创建后添加 数组名[4]=E

    • 修改:

            局部:根据索引修改数组   例如:数组名[0]=F
              整体:可以直接给数组变量重新赋值

    • 读取:

            获取数组中所有的元素:echo ${数组名[*]} 或者 echo ${数组名[@]}
              根据索引读取数组元素:echo ${数组名[索引值]}
              获取数组的长度:echo ${#数组名[*]} 或者 echo ${#数组名[@]}

    • 删除:

            unset 关键字来删除数组元素,格式如下:
                unset  数组名[index]
              不写下标,删除整个数组,格式如下:
                unset 数组名


    6、Shell中的运算符

    • 整数运算语法(默认):

        (1)$(( 运算式 ))   或  $[运算式] 
         (2)运算符   + , - , *, /, %   加,减,乘,除,取余

         (3)运算式要与小扩号之间有空格,中括号的话不用加空格

      (4)expr + , - , *, /, % 加,减,乘,除,取余   注意:expr表达式运算符间要有空格   例如 expr $A  +  $B

    • 小数运算:

           bc:Linux下的一个计算器程序,可以处理整数和小数。Shell 本身只支持整数运算,想计算小数就得使用 bc 这个外部的计算器
            在 Shell 脚本中,借助管道或者输入重定向来使用 bc 计算器。
            语法:echo "scale=要保留的小数位数 ; 计算式" | bc
                expression就是希望计算的数学表达式
            案例1:计算3*8/7 结果保留4位小数
                echo "scale=4; 3*8/7" | bc
            案例2:计算3*8/7 ,再乘5,结果保留3位小数
                echo "scale=3; 3*8/7*5" | bc
            案例4:计算4/9,保留2位,结果赋值给ret变量
                ret=$(echo "scale=2;4/9" | bc)


    7、Shell条件判断

    • 语法:

            注意:条件非空即为true,[ 判断式 ]返回true,[判断式] 返回false。[ 判断式 ](注意判断式前后要有空格)

    • 常用条件判断

        (1)两个整数之间比较
                -lt 小于(less than)
                -le 小于等于(less equal)
                -eq 等于(equal)
                -gt 大于(greater than)
                -ge 大于等于(greater equal)
        -ne 不等于(Not equal)
        (2)按照文件权限进行判断
          -r 有读的权限(read)
            -w 有写的权限(write)
            -x 有执行的权限(execute)
        (3)按照文件类型进行判断
          -f 文件存在并且是一个常规的文件(file)
            -e 文件存在(existence)
            -d 文件存在并是一个目录(判断目录)(directory

    • 案例:

            多条件判断(&& 表示前一条命令执行成功时,才执行后一条命令,|| 表示上一条命令执行失败后,才执行下一条命令)
                [jinghang@hadoop101 ~]$ [ condition ] && echo OK || echo NOTOK
                OK
                [jinghang@hadoop101 ~]$ [ condition ] && [ ] || echo NOTOK
                NOTOK


    8、Shell流程控制 

    • if 判断语句

            注意事项:
            (1)[ 条件判断式 ],中括号和条件判断式之间必须有空格
            (2)if后要有空格

            语法1:
                if [ 条件判断式 ]
                then
                    主体代码
                fi
            语法2:
                if [ 条件判断式 ]
                then
                    主体代码
                else
                    主体代码
                fi
            语法3:
                if [ 条件判断式 ]
                then
                    主体代码
                elif [条件判断式]
                then
                    主体代码
                else
                    主体代码
                fi

    • case 判断语句

            基本语法:
                case $变量名 in
                        "值1")
                        如果变量的值等于值1,则执行程序1
                        ;;
                        "值2")
           如果变量的值等于值2,则执行程序2
              ;;
              …省略其他分支…
                        *)
                        如果变量的值都不是以上的值,则执行此程序
                         ;;
                  esac
            注意事项:
                 1)case行尾必须为单词“in”,每一个模式匹配必须以右括号“)”结束。
            2)双分号“;;”表示命令序列结束,相当于java中的break。
            3)最后的“*)”表示默认模式,相当于java中的default。

    • for 循环语句

            基本语法:
          语法一
              for  (( 初始值;循环控制条件;变量变化 ))
         do
                      逻辑代码
              done
          语法二
                    $* : 读取传入脚本中的全部参数,把参数看作一个整体
                    $@ : 读取传入脚本中的全部参数,把参数区分对待

     

                        for 变量 in "$*或者$@"
                        do
                             逻辑代码
                        done

          注意:for 与 ( 号之间要有空格

    • while 循环语句

            基本语法
          while [ 条件判断式 ]
          do
              逻辑代码
          done
      注意:While 与 [ 号之间要有空格


    9、read读取控制台输入

    • 基本语法:read 【选项】【参数】

          选项
              -p 指定读取值时的提示符;
              -t 指定读取值时等待的时间(秒);
             参数:指定读取值的变量名

    • 案例

          1、请在3秒内输入用户名 

          [root@Linux01 home]# read -p "请在3秒内输入用户名:" -t 3 name
          请在3秒内输入用户名:zhangsan

      2、通过read定制菜单栏

          cat <<-EOF

         1:代表对数据进行倒序排列
          2:代表对数据进行正序排列
         
    EOF

          read -p "请在20秒内输入数字:" -t  20 num


    10、Shell函数  

    •  系统函数

          basename
              basename 命令会删掉所有的前缀包括最后一个(‘/’)字符,然后将字符串显示出来(去掉路径,只显示最后的文件名)
              例如:[root@Linux01 home]# basename /home/test/ccc.txt
              ccc.txt

          dirname
              从给定的包含绝对路径的文件名中去除文件名,然后返回剩下的路径(去掉文件名,只显示文件名之前的绝对路径)
              例如:[root@Linux01 home]# dirname /home/test/ccc.txt
               /home/test

    •  自定义函数

            语法:
          function 函数名()
          {
         方法体
              [return int;]
          }

            编写完脚本之后,执行脚本,就能调用函数了,直接输函数名就可以(在外部调用);在脚本内部调用函数直接函数名就可以。
      经验技巧
            (1)必须在调用函数地方之前,先声明函数,shell脚本逐行运行。不会先编译。
               (2)函数返回值,只能通过$?系统变量获得,可以显示加:return返回,如果不加,将以最后一条命令运行结果,作为返回值。return后跟数值n(0-255)
          创建用户函数(只能当前用户调用)

        1.在用户的家目录中(/home/用户名)找到隐藏文件.bashrc进行编写函数

             2.source  .bashrc

             3.现在就能直接调用函数了

       创建系统函数(所有用户和会话可调用,重启后仍可调用)

        1.root用户在/etc/bashrc文件下编写函数

           2、source  /etc/bashrc

              3.所有用户都可直接调用

     


     

    11、 shell文本处理工具

    •  cut(查看)

          功能描述:cut的工作就是“剪”,具体的说就是在文件中负责剪切数据用的,cut指令用于显示行中的指定部分,删除文件中的指定字段。
            语法:cut 【选项】【文件】
            选项 
                -b <起始字节位置-结束字节位置> 仅显示行中指定字节范围的内容。例如,“-b 2-10”将显示第2~10个字节位置的内容,当只有一个数字时,则仅显示指定字符位置的内容.
                -f <起始列位置-结束列位置> 显示指定列的字段内容
                -d <分隔符> 指定字段的分隔符,默认的字段分隔符为“TAB”
                -c <起始字符位置-结束字符位置> 仅显示行中指定范围的字符。例如,“b2-10” 将显示第2~10个字符位置的内容。当只有一个数字时,则仅显示指定字符位置的内容
       案例:
        切割ifconfig 后打印的IP地址,显示ip地址前3位
          ifconfig eth0 | grep "inet addr" | cut -d : -f 2 | cut -d " " -f 1 | cut -c 1-3

    • sort(查看)

       功能描述:它将文件进行排序,并将排序结果标准输出
      语法:sort 【选项】【参数】
          选项
              -n 依照数值的大小排序
              -r 以相反的顺序来排序
              -t 设置排序时所用的分隔字符
              -k 指定需要排序的列
          参数:是指待排序的文件
      案例:
        将用户列表按照主ID进行倒序排列

        [mayun@Linux01 home]$  sort -t : -nrk 4 /etc/passwd

    • 正则表达式

       概述:正则表达式,又称规则表达式。(英语:Regular Expression,在代码中常简写为regex、regexp或RE)。正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本
      单字符匹配
        d 匹配一个数字字符。等价于[0-9]
        D 匹配一个非数字字符。等价于[^0-9]
        w 匹配包括下划线的任何单词字符。类似但不等价于[A-Za-z0-9_]
        W 匹配任何非单词字符。等价于 [^A-Za-z0-9_]
        s 匹配空白字符,包括空格、制表符、换页符等等,等价于[ f v]
        S 匹配任何可见字符。等价于[^ f v]
        .点 匹配除“ ”和" "之外的任何单个字符
        [a-z] 字符范围,匹配a~z之间的任意字符
        [^a-z] 匹配除了a~z之间的其他字符
         匹配换行符
      多字符匹配
        + 匹配前面的子表达式一次或多次(大于等于1次)
        * 匹配前面的子表达式任意次
        ? 匹配前面的子表达式零次或一次
        {n} n是一个非负整数。匹配确定的n次
        {n,m} m和n均为非负整数,其中n<=m。最少匹配n次且最多匹配m次
      其他
        ^ 匹配输入字行首
        $ 匹配输入行尾
        | 将两个匹配条件进行逻辑“或”(or)运算
          x|y 匹配x或y

      贪婪模式:贪婪模式在整个表达式匹配成功的前提下,尽可能多的匹配   例如: [a-b]*表达式去匹配字符串ababababababbaba,就会全部匹配上

      非贪婪模式:在整个表达式匹配成功的前提下,尽可能少的匹配      例如:[a-b]*?表达式去匹配字符串ababababababbaba,就只会匹配ab

    •  sed

          功能描述:sed是一种单行文本流式编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”,接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件结束。文件内容并没有改变,除非你使用重定向存储输出。
      语法:sed [选项]  ’命令‘    文件名
      选项 功能
        -e 直接在指令列模式上进行sed的动作编辑(一次执行多个操作时)。
        -i 直接编辑文件(修改源文件)
      命令 功能
        p 打印一般 -n 配合使用
        a 新增,在指定的行之后插入内容
        i 新增,在指定的行之前插入内容
        d 删除
        s 查找并替换 (注意:如果进行全局的查找替换 sed  -e  's/查找条件/替换字符串/g' )
      案例:
      数据准备
      (1)将“mei nv”这个单词插入到sed.txt第二行下
        sed  -e '2a mei nv' sed.txt
      (2)删除sed.txt文件所有以wo开头的行
        sed  -e '/^wo/d' sed.txt
      (3)将sed.txt文件中wo替换为ni
        sed  -e  's/wo/ni/g'  sed.txt
        注意:‘g’表示global,全部替换
      (4)将sed.txt文件中的第二行删除并将wo替换为ni
        sed -e '2d'  -e  's/wo/ni/g'  sed.txt
      (5)打开文件注释单行注释的行(删掉第一个#号)
        sed -e  's/^#//g'  sed.txt
       (6) 给文件的前5行内容添加注释
        sed  -e  '1,5s/^/#/g' sed.txt

    •  awk

       功能描述:是一门编程语言,也是一个强大的文本分析工具,逐行扫描文件,默认从第一行到最后一行,寻找匹配特定模式的行,并在这些行上进行你想要的操作。
      语法:awk 选项 'pattern1{action1} pattern2{action2}...' 文件名
      pattern:表示AWK在数据中查找的内容,就是匹配模式,正则表达式
      action:在找到匹配内容时所执行的一系列命令
      选项 功能
        -F 指定输入文件折分隔符
        -v 赋值一个用户定义变量
      案例:
        (1)搜索passwd文件以root关键字开头的所有行,并输出该行的第7列。
            awk -F : '/^root/{print $7}' passwd
        (2)搜索passwd文件以root关键字开头的所有行,并输出该行的第1列和第7列,中间以“,”号分割。
            awk -F : '/^root/{print $1","$7}' passwd
            注意:只有匹配了pattern的行才会执行action
        (3)只显示/etc/passwd的第一列和第七列,以逗号分割,且在所有行前面添加列名user,shell在最后一行添加"总用户数:用户数量"。
            awk -F : 'BEGIN{sum=0;print "user, shell"} {sum=sum+1;print $1","$7} END{print "总用户为:"sum}' passwd

            或者awk -v  sum=0  -F : 'BEGIN{print "user, shell"} {sum=sum+1;print $1","$7} END{print "总用户为:"sum}' passwd
            注意:BEGIN 在所有数据读取行之前执行;END 在所有数据执行之后执行。
        (4)将passwd文件中的用户id增加数值1并输出计算后的用户id和用户名
            awk -v i=1 -F : '{print $1 "," $3+i}' passwd
      awk的内置变量
        变量 说明
          FILENAME 文件名
          NR 已读的记录数
          NF 浏览记录的域的个数(切割后,列的个数)
        案例:
        (1)统计passwd文件名,每行的行号,每行的列数
            awk -F: '{print "filename:" FILENAME ", linenumber:" NR ",columns:" NF}' passwd
        (2)切割IP
            ifconfig eth0 | grep "inet addr" | awk -F: '{print $2}' | awk -F " " '{print $1}'
        (3)查询sed.txt中空行所在的行号
            awk '/^$/{print NR}' sed.txt

     

     

     

  • 相关阅读:
    快排
    SQL实例
    14_可变字符串类和日期相关类
    13_String类的概述和使用
    c# json object Dictionary互转
    SQL Server 数据表给现有字段添加默认值或修改默认值
    SQL Server2008R2 死锁进程杀掉处理
    Sql Server 2008R2 查看SQL语句运行时间
    fatal: unable to access 'https://github.com/xxx': OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection to github.com:443
    idea出现了不能复制的问题
  • 原文地址:https://www.cnblogs.com/si-137/p/13226409.html
Copyright © 2011-2022 走看看