主页
博客
Shell学习.md
Aug 02 2022

了解:

  • shell是帮助应用程序操作Linux内核的工具。
  • Shell解析器有很多(bash,zsh…),但是默认的是bash(mac默认zsh),sh的软连接是bash。
  • shell文件的开头要指定解析器,格式为:#!/bin/bash

基本变量语法:

  • 定义变量,A=2,注意这里的等号两边没有空格
  • 撤销变量:unset A
  • 声明静态只读变量:readonly A=3,注意静态只读变量不能撤销

变量命名规则:

  • 和大部分语言中一样,由字母、数字和下划线组成,但是不能由数字开头,环境变量名称建议大写(如:$HOME)
  • 等号两侧不能有空格
  • 在bash解释器中,变量默认都是字符串类型,无法直接进行数值运算。
  • 变量的值如果有空格需要用双引号或者单引号扩起来。
  • 把变量提升为全局变量:export 变量名(export GOPATH)

特殊变量

  • **$n**:n代表数字,其中$0为当前shell脚本名称,1-9为当前命令后面添加的参数,十以上的参数要用大括号表示,如${10}。
  • **$#**:代表当前所有的参数个数,没有参数则为0。
  • **$*与$@:两个都是获取当前所有的参数列表,只不过*号是一次性获取,把所有的参数看成一个整体,而@**是一个个的获取,区分对待。
  • **$?**:返回一个数值,如果为0则表示上一条shell语句执行成功,如果不为0那么代表执行失败。

‘,“,`符号区分

在bash中“空格”是一种很特殊的字符,比如在bash中这样定义str=this is String,这样就会报错,为了避免出错就得使用单引号’’和双引号””。

单引号’’,双引号””的区别是单引号’’剥夺了所有字符的特殊含义,单引号’’内就变成了单纯的字符。双引号””则对于双引号””内的参数替换($)和命令替换(``)是个例外。

比如说 :

str="hello"   
echo '$str'

结果就是$str,但是改成双引号的话,echo "$str",结果就是hello

``:反引号(esc键下方的那个键),当在脚本中需要执行一些指令并且将执行的结果赋给变量的时候需要使用“反引号”。

例如:

#!/bin/bash
str=`date +'%Y%m%d'`
echo $str
20220802

运算符:

  • 基本语法:

    1. “$((运算式))”或“$[运算式]”
    2. expr + - \* / % 分别对应加减乘除和取余,注意这里的乘号是斜杠加*****号,并且这里的运算符之间是需要有空格的。
  • 案例:

    1. ​ (2+3)*4:

      1.result=$[(2+3)*4]
      2.expr `expr 2 + 3` \* 4
      

条件判断:

  • 基本语法:

    [ condition ],注意condition前后要有空格。条件非空即为true,不非空返回false。

  • 常用条件判断:

    = :字符串比较;-lt:(less than小于);-le:(less equal小于等于);-eq:(equal等于);
    -gt:(greater than大于);-ge(greater equal大于等于);-ne(not equal不等于)。
    
  • 按照文件权限进行判断:

    -r,-w,-x:分别代表有读、写、可执行的权限
    
  • 按照文件类型进行判断:

    -f:文件存在,且是一个常规的文件;-e:文件存在exitense;-d:文件存在,且是一个目录directory
    
  • 多条件判断:(&&表示前一条命令执行成功时,才执行后一条命令,||表示上一条命令执行失败后才执行下一条命令)

  • 例子:

    1.判断23是否大于22:[ 23 gt 22 ]
    2.判断文件是否有写权限:[ -w helloworld.sh ]
    3.判断/home/self/hello.sh是否存在:[ -e /home/self/hello.sh ]
    3.[ condition ] && echo OK || echo “not ok”
    

流程控制:

  1. if判断:
    if [ command ];then
       符合该条件执行的语句
    elif [ command ];then
       符合该条件执行的语句
    else
       符合该条件执行的语句
    fi
    

    或者

    if [ command ]
    then
       符合该条件执行的语句
    elif [ command ]
    then
       符合该条件执行的语句
    else
       符合该条件执行的语句
    fi
    
  2. case语句

    基本语法:

    case 变量 in
    条件 1)
          执行代码块1
          ;;
    条件 2)
          执行代码块2
          ;;
    条件 3)
          执行代码块3
          ;;
    *)
          无匹配后命令序列
     esac
    
  3. for循环

    1.c语言风格
    for ((i=1; i<=100; i++)) #这里用双括号将循环条件扩起来
    do
        echo $i
    done
    2.python风格
    for i in {1..100} #或者这里用之前提到的$*、$@。	
    do
        echo $i
    done
    3.seq使用
    for i `seq 1 100`
    do
        echo $i
    done
    
  4. while循环

    whilei [ condition ]
    do
        程序
    done
    

read读取控制台输入

  • 语法:read(选项)(参数)

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

系统函数

  • basename:用法:basename string/pathname suffix ,如果有后缀suffix的话,那么会将string或者pathname中的suffix去除。

    basename /home/ouyangcan/test.sh -> /home/ouyangcan/test.sh
    basename /home/ouyangcan/test.sh .sh -> /home/ouyangcan/test
    
  • dirname:用法:dirname 文件绝对路径 (从给定的包含文件名的绝对路径中去除掉文件名,返回剩下的目录部分。)

    dirname /home/ouyangcan/test.sh -> /home/ouyangcan
    

自定义函数

  • 语法:
[function] funname[()]
{
    Action;
    [return int];
}
funname #最后通过funname来调用
注:
1.其中中括号扩起来的部分都是可写可不写的部分。
2.要想调用函数,必须先声明,shell脚本逐行运行,不会预先编译。
3.函数返回值只能通过$?系统变量获得,可以显示加return返回,不加的话就以最后一条语句的运行结果作为返回值。return后跟0~255

shell工具

  • cut

​ 在文件中负责剪切数据用,从文件的每一行剪切字节、字符和字段将他们输出。

cut [选项参数] filename
-f:列号,提取多少列
-d:分隔符,按照指定分隔符分割列
eg:cut -d " " -f 1,2 cut.txt	(-2表示从1到2,2-表示2和2后面的所有列)
  • sed

​ sed是一种流编辑器,一次处理一行内容,处理时把当前处理行存储在临时缓冲区中,成为“模式空间”,接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送完屏幕,接着处理下一行,不断重复直到文件末尾,而文件内容并没有改变,除非你使用重定向存储输出。

sed [选项参数] 'command' filename
选项参数:-e,直接在指令模式上进行的动作编辑,只有一个命令不需要加-e,多个命令则需要逐次在每个命令钱添加-e。
command:
    a:a的后面可以接字串,在下一行出现。 #sed "2a mei mv" sed.txt,在第二行插入mei nv
    d:删除 #sed "/wo/d" sed.txt,删除包含wo的行
    s:查找并替换	#sed "s/wo/ni/g" sed.txt	#将文件中的wo全部替换成ni,如果不加/g则只替换第一个wo。g表示global。
  • awk

​ 一个强大的文本分析工具,把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行分析处理。

awk [选项参数] 'pattern1{action1} pattern2{action2} ...' filename
pattern:表示awk在数据中查找的内容,就是匹配模式。
选项参数:
    -F:指定输入文件的分隔符
    -v:赋值一个用户定义变量 #-v i=1
    $n:n表示数字,如果为0的话表示所有的内容,其他的则为第n列的内容。
    eg:
    awk -F : 'BEGIN{print "user,shell"} {print $1","$7} END{print "ouyangcan,/bin/nbsh"}' passwd
内置变量:
    FILENAME:文件名;NR:已读的记录数;NF:浏览记录的域的个数(切割后列的个数)
    eg:awk -F : '{print FILENAME "," NR "," NF}' passwd
  • sort

​ 将文件进行排序,并将排序结果标准输出。

sort (选项)(参数)
选项:
    -n:依照数值的大小排序
    -r:依照数值的顺序排序
    -t:设置排序时使用的分隔字符
    -k:指定需要排序的列
eg:
    sort -t : -nrk 2 sort.sh
  • grep:

    grep (global search regular expression(RE) and print out the

line,全面搜索正则表达式并把行打印出来)是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来。用于过滤/搜索的特定字符。可使用正则表达式能多种命令配合使用,使用上十分灵活。

  • getopts:

    经常和while和case一起使用,一般用法:

    while getopts 'h:j:m:u' OPT; do
        case $OPT in
            j) S_DIR="$OPTARG";;
            m) D_DIR="$OPTARG";;
            u) upload="true";;
            h) func;;
            ?) func;;
        esac
    done
    
    echo $S_DIR
    echo $D_DIR
    echo $upload
    
    sh test.sh -j /data/usw/web -m /opt/data/web	#选项后面跟着的就是OPTARG。
    ##输出结果
    /data/usw/web
    /opt/data/web
    false
    
  • ps:

    Linux中的ps命令是Process Status的缩写。ps命令用来列出系统中当前运行的那些进程。ps 为我们提供了进程的一次性的查看,它所提供的查看结果并不动态连续的;ps命令列出的是当前那些进程的快照,就是执行ps命令的那个时刻的那些进程,如果想要动态的显示进程信息,就可以使用top命令。

使用方式:ps [options] [--help]
说明:显示瞬间行程 (process) 的动态
参数:ps的参数非常多, 在此仅列出几个常用的参数并大略介绍含义
-A 列出所有的进程
-w 显示加宽可以显示较多的资讯
-au 显示较详细的资讯
-aux 显示所有包含其他使用者的行程