zoukankan      html  css  js  c++  java
  • shell语言学习(更新中)

    1、概念

    Shell是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务, Shell脚本(shell script),是一种为Shell编写的脚本程序。我们经常说的shell通常都是指shell脚本。

    2、脚本输出方法

    a、echo [选项] [内容]

     当选项为 -e的时候,内容里面出现以上的内容时,就会识别上表中的符号

    如 echo -e 'hello' => 输出 helo

    echo输出颜色表示:echo  -e  "e[1;31mthis is test e[0m"

    #30m: 黑色   #31m:红色    #32m:绿色    #33m:黄色     #34m:蓝色     #35m:洋红       #36m:青色    #37m:白色

    3、脚本的声明

    #!/bin/bash    //可以用echo $SHELL进行查看
    echo 'hello world!'

    说明:

    • #! 告诉系统这个脚本需要什么解释器来执行。
    • 文件扩展名 .sh 不是强制要求的。
    • 方法1 直接运行解释器,hello.sh 作为 Shell 解释器的参数。此时 Shell 脚本就不需要指定解释器信息,第一行可以去掉。
    • 方法2 hello.sh 作为可执行程序运行,Shell 脚本第一行一定要指定解释器。

    注意:在shell中常常会看到exit 0 这里的0表示成功退出非0表求错误退出。

    4、脚本的运行

    // 方法1
    sh hello.sh
    
    // 方法2
    chmod +x hello.sh
    ./hello.sh

    // 方法3
    sh hello.sh

    5、shell变量

    定义:Shell 变量分为系统变量和自定义变量。系统变量有$HOME、$PWD、$USER等,显示当前 Shell 中所有变量:set 。

    变量名可以由字母、数字、下划线组成,不能以数字开头。

    #!/bin/bash
    name='testName'  //注意:这里是不能有空格的
    readonly name      //一旦声明了readonly,那么这个为师是只读的,不允许更改
    //使用变量 
    echo $name
    //或者
    echo ${name}

    删除变量

    #!/bin/bash
    name='aaa';
    readonly name;
    age=20;
    unset name;   //readonly 的变量是不能被删除
    unset age;      //可以被删除

    注意:变量的定义与变量的删除都不用$符来修饰

    通常上面定义的是全局变量,不建议定义全局变量,可以使用局部变量,在变量前面添加local 关键字

    # 定义局部变量
    function test2(){
      local -i a=3      //如果declare与local并在的时候,写法可以省去declare
      declare -i b=3
    }

     6、shell字符串

     双引号的字符串拼接

    #!/bin/bash
    name='bill';
    age=20;
    echo -e "e[1;34m 我的名字叫"${name}"我今年"$age"岁了e[0m";
    echo -e "e[1;35m 我的名字叫${name},我今年${age}岁了e[0m";

    双引号可以解析引号内的内容

    your_name='runoob'
    str="Hello, I know you are "$your_name"! 
    "
    echo -e $str

    单引号的字符串拼接

    # 使用单引号拼接
    greeting_2='hello, '$your_name' !'
    greeting_3='hello, ${your_name} !'
    echo $greeting_2  $greeting_3

    获取字符串的长度

    #!/bin/bash
    name="are you ok   ???";
    echo "name的长度是:${#name}";
    echo "name的长度是"`expr length "$name"`;

    提取查询的子串的长度

    echo `expr match "$name" today`  //输出5
    echo `expr match $name good` //输出0

    注意:这里是需要从第一位开始匹配的

    提取子字符串

    注意:第三个方法的负数最好有一个空格,或者采用第四种方法,表示的是从左边截取几位数

    #!/bin/bash
    str="bill is super man!";
    echo "第二个字符到第六个字符是${str:2:6}";
    #输出 第二个字符到第六个字符是ll is
    echo ${str: -3}  //输出 an! 注意中间需要有一个空格
    string="abcdefghijklmnopqrstuvwxyz";
    echo ${str: -12:3}  //输出opq  注意从右边开始算,取正常顺序的3个字符

    查找子字符串

    查找是从第1位开始,如果没有找到那么就返回0,例如查找ac是先查找a然后再查找c,看哪个先找到,那么就返回先找到的部份,当a与c都能找到的情况下,返回比较小的值

    #!/bin/bash
    str="abcdefghijklmnopqrstuvwxyz";
    echo `expr index "$str" s`;
    echo `expr index "$str" ac`;

    注意: 以上脚本中 ` 是反引号,而不是单引号 ',不要看错了哦。

    变量替换

     举例:

    #!/bin/bash
    str="I see a yellow duck looking at me";
    clip1=${str#*a};
    clip2=${str##*a};
    echo $clip1;                //输出 yellow duck looking at me
    echo $clip2;                //输出 t me
    clip3=${str%a*};
    clip4=${str%%a*};
    echo $clip3;               //输出 I see a yellow duck looking
    echo $clip4;               //输出 I see
    clip5=${str/a/bb};
    clip6=${str//a/bb};
    echo $clip5;               //输出 I see bb yellow duck looking at me
    echo $clip6;               //输出 I see bb yellow duck looking bbt me

    文本练习

    #!/bin/bash
    str="Bigdata process framework is Hadoop, Hadoop is an open source project";
    
    function show_tip() {
      echo "*******************************";
      echo "(1)打印string的长度";
      echo "(2)删除字符串中所有的Hadoop";
      echo "(3)替换第一个Hadoop为Mapreduce";
      echo "(4)替换全部Hadoop为Mapreduce";
      echo "*******************************"
    }
    
    function show_len() {
      echo "string的长度是${#str}";
    }
    
    function del_str() {
      echo ${str//Hadoop};
    }
    
    function rep_str() {
      echo ${str/Hadoop/Mapreduce};
    }
    
    function rep_all_str() {
      echo ${str//Hadoop/Mapreduce};
    }
    
    
    while true;
    do
      echo "【str=$str】";
      show_tip;
      read -p "请选择对应的操作1|2|3|4|q|Q: " choice
      case $choice in
        1) show_len;;
        2) del_str;;
        3) rep_str;;
        4) rep_all_str;;
       q|Q) exit;;
        *) echo "输入有误,请重新输入(1|2|3|4|q|Q)";
      esac
    done

    7、数组

    bash支持一维数组(不支持多维数组),并且没有限定数组的大小。

    类似于 C 语言,数组元素的下标由 0 开始编号。获取数组中的元素要利用下标,下标可以是整数或算术表达式,其值应大于或等于 0。

    数组的定义

    数组名=(值1 值2 ... 值n)

    也可以采用各个项来定义

    array_name[0]=value0
    array_name[1]=value1
    array_name[n]=valuen

    输出数组

    #!/bin/bash
    arr=("a" "b" "c" "d");
    echo ${arr[0]};        //输出第0项
    echo ${arr[@]};        //输出所有项数组          

    输出数组的长度

    #!/bin/bash
    arr=("aa" "bbb" "cccc" "ddddd");
    echo "数组的长度是"${#arr[@]};              //输出4
    echo "这个也是数组的长度"${#arr[*]};         //输出4
    echo "这个是数组中单项的长度"${#arr[3]};      //输出5   

    8、函数的定义

    函数的定义方式:

    $n表示输出第n位参数,$@与$*的意思一样表示输出所有的参数,$#表示参数的个数

    #!/bin/bash
    function func() {
      echo $1,$@;
    }
    func "gaga";

     练习:

    #!/bin/bash
    
    function count {
      case $2 in
        +) echo `expr $1 + $3`;;
        -) echo `expr $1 - $3`;;
        *) echo `expr $1 * $3`;;
        /) echo `expr $1 / $3`;;
      esac
    }
    
    count $1 $2 $3
    
    
    //调用的时候  sh bash.sh 12 + 2

    函数的返回值

     return 返回值 只能返回1-255的整数。通常return只是用来供其他地方调用获取状态,因此通常仅返回0或1;0表示成功,1表示失败

     echo 返回值可以返回任何字符串结果 。通常echo用于返回数据,比如一个字符串值或者列表值。

    #!/bin/bash
    
    function getUser {
      user=$(cat /etc/passwd|cut -d ":" -f 1);
      echo $user;       //返回值是查询结果
    }
    
    data=`getUser`;
    
    for var in $data;
    do
      echo $var;
    done;
    exit;
     

    9、shell中的read命令

    简单读取

    #!/bin/bash
    echo "请输入任意的内容";
    read content;                        //把输入的内容赋值给content这个变量
    echo "你输入的内容是"$content;
    • -p 后面跟提示信息,即在输入前打印提示信息。
    • -t 后面跟秒数,定义输入字符的等待时间。
    • -s 安静模式,在输入字符时不再屏幕上显示,例如login时输入密码。
    • -n 后跟一个数字,定义输入文本的长度,很实用。
    #!/bin/bash
    read -p "请输入任意的内容:" content;
    echo "你输入的内容是:"$content;
    #!/bin/bash
    if read -t 5 -p "请5秒内输入用户名:" user;    //这里在-t后面跟数据可以有空格,也可以没有空格
    then
      echo "您输入的用户名是:"$user;
    else
      echo "对不起,你输入超时";
    fi
    exit 0;
    #!/bin/bash
    read -n1 -p "请选择Y|N" sign          //这里的-n后面跟数据可以有空格,也可以没有空格
    echo "你输入的是:"$sign;

     10、字符串的运算符

    使用[[ ... ]]条件判断结构,而不是[ ... ],能够防止脚本中的许多逻辑错误。比如,&&、||、<和> 操作符能够正常存在于[[ ]]条件判断结构中,但是如果出现在[ ]结构中的话,会报错。比如可以直接使用if [[ $a != 1 && $a != 2 ]], 如果不适用双括号, 则为if [ $a -ne 1] && [ $a != 2 ]或者if [ $a -ne 1 -a $a != 2 ]。

    #!/bin/bash
    read -n1 -p "请输入对应的指令Y|N" sign;
    if [[ $sign = "Y" || $sign = "y" ]]            //这里的[[]]的前后都要加上空格,在if后面也要加上空格
    then
      echo "你输入的是肯定的回答";
    elif [[ $sign = "N" || $sign = "n" ]]
    then
      echo "你输入的是否定的回答";
    else
      echo "输入的字符不合法,请输入Y|N";
    fi
    exit 0;

    11、流程控制语句

    if...elif...else例子如上

    case 语句,相当其他语法的switch

    #!/bin/bash
    num=12;
    case $num in
      1|2|3|4|5|6|7|8|9) echo '这个值是小于10的值';;
      10) echo "这个值是等于10的值";;
      *) echo "这个值是大于10的值";;
    esac
    exit 0;

    for语名的使用

    #!/bin/bash
    for((i=0; i<=10; i++)); do
    echo "现在输出的是"${i};
    done;
    exit 0;

    注意:这里使用的是双括号

    #!/bin/bash
    arr=("aa" "bb" "cc" "dd" "ee");
    for per in ${arr[@]};
    do
      echo "值为"$per;
    done
    
    exit 0;

    while的使用

    #!/bin/bash
    int=1
    while(( $int<=5 ))
    do
        echo $int
        let "int++"
    done

    注意:这里的Let相当于(())的用法

    12、命令替换

    #!/bin/bash
    echo $(date +%Y);
    echo `date +%Y`;
    echo "明年是"$((`date +%Y` + 1))"";
    echo "明年是"$(($(date +%Y) + 1))"";

    如果没有命令替换,那么会输出命令

    #!/bin/bash
    //当本机的ngnix进程没有的时候,那么重新启动nginx服务
    nginx_process_num = $(ps -ef | grep nginx | grep -v grep | wc-1)   //重点表示过滤
    if [ $nginx_process_num -eq 0 ];
    then
      systemctl start nginx
    fi

     13、cut的使用

    常用命令  cut  -d  ":"  -f  1  表示从字符串中截取一部份 -d:表示自定义分隔符,默认为制表符,“:” 表示以:进行分割, -f:与-d一起使用,指定显示哪个区域。1:表示取第一部份

    #!/bin/bash
    name="this is test are you ok???";
    echo $name|cut -d " " -f 1;    //输出 this

     14、wc的使用

    在默认的情况下,wc将计算指定文件的行数、字数,以及字节数。使用的命令为:

    wc testfile

    • -l或--lines 只显示行数。
    • -w或--words 只显示字数。
    wc test.sh   //输出  6 11 72 bash.sh
    ls -l|wc -l    //输出 3  表示有3条记录

     15、bc的使用

    bc 命令是任意精度计算器语言,通常在linux下当计算器用。一般来讲,等式的小数位数决定了答案的位数

    #!/bin/bash
    echo "scale=2;3/8" | bc;       //输出 0.37
    echo "0.356 * 2" | bc;          //输出0.712
            

     

    向上取整与向下取整的函数封装

    parseFloat() {
        echo "$1 + 0.000" | bc
    }
    
    floor() {
        a=$(parseFloat $1)
        b=$(parseFloat $2)
        echo `echo "scale=0; $a/$b" | bc`
    }
    
    ceil() {
        a=$(parseFloat $1)
        b=$(parseFloat $2)
        num=$(echo "scale=2; $a/$b" | bc)
        int=$(floor $a $b)
    
        if [ $(echo "$int < $num"|bc) -eq 1 ];
        then
            echo $(($int+1))
        else
            echo $int;
        fi
    }
    
    round() {
        a=$(parseFloat $1)
        b=$(parseFloat $2)
        num=$(echo "scale=2; $a/$b" | bc)
        int=$(floor $a $b)
        middle=$(echo "$int + 0.5" | bc)
    
        if [ $(echo "$middle < $num"|bc) -eq 1 ];
        then
            echo $(($int+1))
        else
            echo $int;
        fi
    }
    
    echo $(floor 11 3) 3
    echo $(floor 12 3) 4
    echo $(floor 13 3) 4
    echo $(floor 14 3) 4
    echo $(ceil 11 3) 4
    echo $(ceil 12 3) 4
    echo $(ceil 13 3) 5
    echo $(ceil 14 3) 5
    echo $(round 11 3) 4
    echo $(round 12 3) 4
    echo $(round 13 3) 4
    echo $(round 14 3.3) 4
    echo $(round 15 3) 5

     16、ps的用法

    ps命令 用于报告当前系统的进程状态。可以搭配kill指令随时中断、删除不必要的程序。ps命令是最基本同时也是非常强大的进程查看命令,使用该命令可以确定有哪些进程正在运行和运行的状态、进程是否结束、进程有没有僵死、哪些进程占用了过多的资源等等,总之大部分信息都是可以通过执行该命令得到的。

    以下是ps的常用用法

    ps axo pid,comm,pcpu # 查看进程的PID、名称以及CPU 占用率
    ps aux | sort -rnk 4 # 按内存资源的使用量对进程进行排序
    ps aux | sort -nk 3  # 按 CPU 资源的使用量对进程进行排序
    ps -A # 显示所有进程信息
    ps -u root # 显示指定用户信息
    ps -efL # 查看线程数
    ps -e -o "%C : %p :%z : %a"|sort -k5 -nr # 查看进程并按内存使用大小排列
    ps -ef # 显示所有进程信息,连同命令行
    ps -ef | grep ssh # ps 与grep 常用组合用法,查找特定进程
    ps -C nginx # 通过名字或命令搜索进程
    ps aux --sort=-pcpu,+pmem # CPU或者内存进行排序,-降序,+升序
    ps -f --forest -C nginx # 用树的风格显示进程的层次关系
    ps -o pid,uname,comm -C nginx # 显示一个父进程的子进程
    ps -e -o pid,uname=USERNAME,pcpu=CPU_USAGE,pmem,comm # 重定义标签
    ps -e -o pid,comm,etime # 显示进程运行的时间
    ps -aux | grep named # 查看named进程详细信息
    ps -o command -p 91730 | sed -n 2p # 通过进程id获取服务名称

    例如查找linux中nginx的进程 ps -ef| grep nginx | grep -v grep

    17、有类型的变量(即类型声明)

    在shell中进行变量类型声明,需要通过declare和typeset两个命令进行操作,这两者是等价的, 下在以declare为例:

     注意:声明了环境变量后,在脚本中就可以直接使用

     取消声明的变量

    取消声明的变量
    declare +r  取消只读
    declare +i  取消只为整型
    declare +a  取消只为数组
    declare +x  取消只为环境变量

     18、bash数学运算之expr

    语法:

     注意:expr后面每个单语需要有空格,operator表示运算符

     

    注意:在expr运算中,特殊的符号需要加上转义符号

    #!/bin/bash
    num1=100;
    num2=200;
    num3=$(expr $num1 + $num2);  //使用这种语法,在赋值的时候需要进行转义
    num4=`expr $num2 + $num3`;
    num5=$(($num3 + $num4));
    echo $num3;
    echo $num4;
    echo $num5;

     注意:$(())不是一个表达式,但是可以进行赋值, expr是一个表达式,命令,可以单独运行,所以在expr进行赋值的时候,需要进行命令的替换。

     练习:

    [root@instance-yvmni62c ~]# cat bash.sh
    #!/bin/bash
    
    info() {
      echo "********************************************";
      echo "输入一个数求和";
      echo "********************************************";
    }
    
    isInt() {
      num=$(echo "scale=0; $1/1"|bc);
      echo `expr $num >= $1`;
    }
    
    getTotal() {
      num=0;
      for((i=0; i<=$1; i++)); 
      do
        num=$(($num + $i));
      done
    
      echo "总和是"$num;
    }
    
    
    while true
    do
      info;
      read -p "请输入一个数:" count;
      echo $count;
      if [ $count -gt 0 ] && [ $(isInt $count) -eq 1 ]
      then 
       getTotal $count;
      else 
        echo "输入的数字格式有误";
      fi
    done

     判断是否是正整数

    #!/bin/bash
    read -p "输入一个数 " count;
    expr $count  + 1 &> /dev/null;
    echo $?;    //输出0表是是正整数  1是负数  2是小数

     19、sleep表示睡眠

    sleep(参数)

    #!/bin/bash
    
    b=''
    for ((i=0;$i<=100;i++))
     do
     printf "Progress:[%-100s]%d%%
    " $b $i
     sleep 0.1
     b=#$b
     done
    echo

     20、find的使用细节

     常用选项配置

    find命令总结
    常用选项:
    -name          查找/etc目录下以conf结尾的文件 find /etc -name '*conf'
    -iname         查找当前目录下文件名为aa的文件,不区分大小写 find . - iname aa
    -user          查找文件属主为hdfs的所有文件 find . -user hdfs
    -group         查找文件属组为yarn的所有文件 find,- group yarn
    -type
             f           文件                            find . -type f
             d           目录                            find . -type d
             c           字符设备文件                     find . -type c
             b           块设备文件                       find . -type b
             l           链接文件                        find . -type l
             p           管道文件                        find . -type p
    -size
            -n           大小大于n的文件
            +n           大小小于n的文件
            n            大小等于n的文件
    例子1:查找/etc目录下小于10000字节的文件   find /etc -size -10000c
    例子2:查找/etc目录下大于1M的文件   find /etc -size +1M
    -mtime
           -n            n天以内修改的文件
           +n            n天以外修改的文件
           n             正好n天修改的文件
    例子1:查找/etc目录下5天之内修改且以con结尾的文件 find /etc -mtime -5 -name '*.conf'
    例子2:查找/etc目录下10天之前修改且属主为xoot的文件 find/etc -mtime +10 -user root

     对查找到的结果进行操作

    语法  find【路径】【选项】【操作】-exec command {} ;

    例子:

     

     练习:

    #!/bin/bash
    
    if [ ! -d 'abc' ];
    then
      echo "文件夹不存在的哈";
      exit;
    fi
    
    function dealFile {
      cd ~;
      mkdir -p 'bf/conf';
      mkdir -p 'bf/sh';
      cd "abc";
      find ./ -name "*.conf" -exec mv {} ../bf/conf/ ;
      wait $!      #等待上个命令执行完成
      find ./ -name "*.sh" -exec mv {} ../bf/sh ;
      wait $!;
      cd ~;  
      rm -rf abc;
      mv bf abc;
      cd abc;
    }
    
    #对所对应的两个文件夹进行压缩处理,conf采用bz2压缩,sh采用gz压缩
    
    function packFile {
      tar -jcvf conf.tar.bz2 ./conf
      tar -zcvf sh.tar.gz ./sh
      #删除原有的目录
      rm -rf conf sh;
    }

     21、grep与egrep的使用

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

    egrep: 用于在文件内查找指定的字符串。egrep执行效果与grep -E相似,使用的语法及参数可参照grep指令,与grep的不同点在于解读字符串的方法。

     grep的语法格式:

     ◆第一种形式:   grep [option] [ pattern] [file1,file2...]   这种形式主要是在文件中查找,遍历文件的每一行,如果有匹配的就把那行列出来;

     ◆第二种形式:  command | grep [option][pattern]  这种形式主要是在命令的终端中进行查找 

    grep常用的配置选项

     grep -r ~/   表示在~目录下对所有文件进行递归查询,在普通文件下是没有意义的。

     

     22、rpm的使用

    rpm命令 是RPM软件包的管理工具。在查询nginx的时候可以使用 rpm -ql nginx来查询相应的信息

     23、sed的工作模式

    sed:流编辑器。对标准输出或文件逐行进行处理

    sed的语法格式:

      ◆第一种形式: stdout | sed  [option]  "pattern command"

      ◆第二种形式:sed [option] "pattern command" file

    sed的选项

    sed 'p' test.txt  //这里的p是个命令表示print的意思 , 原来sed有打印的意思,所以这里会输出2次
    sed -n 'p' test.txt  // -n表求静默模式,会取消原来默认的打印模式,所以只会打印一次
    sed -n '/day/p' test.txt // 这里的day表示查询匹配的意思,后面的p表示print(以行为单位进行匹配),也可以是day.*表示匹配day后面有的所有字符

     -e可以理解成或的关系,如果有有一个可以不写,但是有多个就都要写

    sed -n -e  '/day/p'  -e '/ok/p' test.txt   //表示输出含day,也输出含有ok的行

    -f可以理解为file,例如新建一个文件key.txt里面的内容是 /ok/p

    sed -n -f key.txt test.txt   //表示把key.txt中的内容拿到test.txt中进行匹配

     -r表示正则表达式

    sed -n -r '/ok|day/p' test.txt

    -i表示修改文件内容

    sed -n -i 's/day/today/g;p' test.txt   //表示把文中的day 改成today;p表示输出(可省),如果没有-i那么只是把改的结果输出给你,原文不更改,加-i后会更改原文件

     set中的pattern祥解表示匹配模式

    30、$()与${}, $(()), []的区别

    shell中要对一个命令的结果做操作这时候就要用到$(),但是如果只对一个变量做操作的时候就要用到${}

    $(())是用来作整数运算的。在bash中, $(())的整数运算符号大致有这些:

    • +- * / #分别为”加、减、乘、除”。
    • % #余数运算,(模数运算)
    • & | ^ ! #分别为”AND、OR、XOR、NOT”运算。

    [ ] :即为test命令的另一种形式。

    但要注意许多:

    1.你必须在左括号的右侧和右括号的左侧各加一个空格,否则会报错。

    2.test命令使用标准的数学比较符号来表示字符串的比较,而用文本符号来表示数值的比较。很多人会记反了。使用反了,shell可能得不到正确的结果。

    #!/bin/bash
    str="this is text";
    #使用变量
    echo "这是一个测试文本"${str};
    #使用一个命令的结果做操作
    for var in $(cat /etc/passwd|cut -d ":" -f 1)
    do
      echo $var;
    done

     if语句中用[]来判定,常用等式中用$(())来获取结果

  • 相关阅读:
    基于flask的web微信
    Scrapy框架
    python爬虫之Selenium
    python爬虫之request and BeautifulSoup
    CMDB的四种模式
    Django之CURD插件2
    Django之CURD插件
    在代码中使用Autolayout – intrinsicContentSize和Content Hugging Priority
    iOS事件传递&响应者链条
    CAEmitterLayer 粒子发射Layer的相关属性
  • 原文地址:https://www.cnblogs.com/rickyctbu/p/12166039.html
Copyright © 2011-2022 走看看