• Linux 笔记


    博客地址:http://www.moonxy.com

    一、前言

    常见的编程语言分为两类:一类是编译型语言,如:C、C++ 和 Java等,它们远行前要经过编译器的编译。另一类是解释型语言,不需要编译,执行时,需要使用解释器一行一行地解释执行,如:awk、perl、python 和 shell 等。

    Shell 是一种脚本语言,属于上面提到的第二类语言,就必须有对应的解释器来执行这些脚本,最常见的脚本解释器是:bash。

    在编写 Shell 脚本时,我们不仅会用到很多的 Linux 命令、正则表达式、管道符、数据流重定向等语法规则,还需要把内部功能模块化后通过逻辑语句进行处理,最终形成常见的 Shell 脚本。

    1.1 查看系统支持的 Shell 种类

    Linux 的 Shell 种类众多,常见的有:
    Bourne Shell(/usr/bin/sh或/bin/sh)
    Bourne Again Shell(/bin/bash)
    C Shell(/usr/bin/csh)
    K Shell(/usr/bin/ksh)
    Shell for Root(/sbin/sh)

    可以通过查看 /etc/shells,知道当前系统所支持的所有 shell 类型及路径,如下:

    [root@ryan ~]# cat /etc/shells
    /bin/sh
    /bin/bash
    /sbin/nologin
    /bin/dash
    ……

    Bourn Shell 是最早流行起来的一个 Shell 版本,其创始人是 Steven Bourn,为了纪念他而将其命名为 Bourn Shell,简称 sh。RedHat 系列的 Linux 发行版默认也安装了 Bash,也就是 Bourne Again Shell,由于易用和免费,Bash 在日常工作中被广泛使用。同时,Bash 也是大多数Linux 系统默认的 Shell。

    1.2 查看当前用户使用的 Shell 种类

    可以通过执行 echo $SHELL 查看,如下:

    [root@ryan ~]# echo $SHELL
    /bin/bash

    或者查看 /etc/passwd,以查看 root 用户的 Shell 类型为例,如下:

    [root@ryan ~]# cat /etc/passwd | grep ^root
    root:x:0:0:root:/root:/bin/bash

    最后一个:号后显示的字段即为 root 用户的登录 shell 类型,此处为 bash。

    也可以直接输入命令 echo $0 查看,但需要注意的是并不是所有的 Shell 都支持,如下:

    [root@ryan ~]# echo $0
    -bash

    当然也可以在当前环境变量中查看,如下:

    [root@ryan ~]# env | grep SHELL
    SHELL=/bin/bash

    其实,查看当前用户 Shell 种类的方法还有很多。

    1.3 查看 Shell 版本

    在获得当前使用的 shell 的类型后,用户可以直接使用 shell 相关的命令参数获取其版本号,一般都可以使用 --version 参数来获取 shell 的版本号,如下:

    [root@ryan ~]# bash --version
    GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu)
    Copyright (C) 2009 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

    This is free software; you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law.

    二、常用 Shell 操作

    2.1 命令 date

    date 命令的常用的格式化选项:

    date +%Y:表示以四位数字格式打印年份;

    [root@ryan ~]# date +%Y
    2018

    date +%y:表示以两位数字格式打印年份;

    [root@ryan ~]# date +%y
    18

    date +%m:表示月份;

    [root@ryan ~]# date +%m
    04

    date +%d:表示日期;

    [root@ryan ~]# date +%d
    14

    date +%H:表示小时;

    [root@ryan ~]# date +%M
    13

    date +%M:表示分钟;

    [root@ryan ~]# date +%M
    04

    date +%S:表示秒;

    [root@ryan ~]# date +%S
    46

    date +%w:表示星期,如果结果显示 0 则表示周日;

    [root@ryan ~]# date +%w
    6

    date +%F:表示年月日;

    [root@ryan ~]# date +%F
    2018-04-14

    date +%T:表示时分秒;

    [root@ryan ~]# date +%T
    14:08:57

    date +"%Y-%m-%d %H:%M:%S",显示如下:

    [root@ryan ~]# date +"%Y-%m-%d %H:%M:%S"
    2018-04-14 14:10:43

    date +"%F %T",显示和上面相同。

    有时候会用到前一天的日期,如下:

    [root@ryan ~]# date -d "-1 day" +"%d"
    13

    或者后一天的日期,如下:

    [root@ryan ~]# date -d "+1 day" +"%d"
    15

    同理可以设置小时,分钟等。

    2.2 数学运算

    数学运算的时候要用 [ ] 括起来,并且前面要加符号 $

    [root@ryan ~]# a=2;b=3
    [root@ryan ~]# ab=$[$a+$b]
    [root@ryan ~]# echo $ab
    5

    定义变量的格式是:

    变量名=变量值

    定义之后引用该变量时要加上符号 $,如下:

    $ab

    如果变量的值是 shell  命令,则需要加反引号,它的作用是将引号中的字符串当成 shell 命令来执行。

    2.3 和用户交互

    read 命令用于和用户交互,它把用户输入的字符串作为变量值。如下:

    [root@ryan shelltest]# cat readtest.sh
    #!/bin/bash
    ## This Shell script is used for testing read
    read -p "Please input a number:" n
    echo $n

    [root@ryan shelltest]# ./readtest.sh
    Please input a number:5
    5

    也可添加 -t 选项,设置 3 秒后退出,如下:

    read -t 3 -p "Please input a number:" n

    2.4 Shell 脚本预设的特殊变量

    $* 和 $@ 的区别为: $* 和 $@ 都表示传递给函数或脚本的所有参数,不被双引号(" ")包含时,都以"$1" "$2" … "$n" 的形式输出所有参数。但是当它们被双引号(" ")包含时,"$*" 会将所有的参数作为一个整体,以"$1 $2 … $n"的形式输出所有参数;"$@" 会将各个参数分开,以"$1" "$2" … "$n" 的形式输出所有参数。

    $? 可以获取上一个命令的退出状态。所谓退出状态,就是上一个命令执行后的返回结果。退出状态是一个数字,一般情况下,大部分命令执行成功会返回 0,失败返回 1。

    2.5 转义字符

    在 echo 中可以用于的转义字符有:

    2.6 Shell 中的引号

    Shell 中的引号主要有单引号双引号反引号

    单引号

    单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的;

    单引号字串中不能出现单引号(对单引号使用转义符后也不行)。

    [root@ryan shelltest]# echo '$HOME'
    $HOME

    双引号

    双引号里可以有变量;

    双引号里可以出现转义字符。

    [root@ryan shelltest]# echo "$HOME"
    /root

    反引号

    反引号中的字符串当成 shell 命令来执行。

    [root@ryan shelltest]# echo Today is `date +%F`
    Today is 2018-04-14

    得到文件名,使用 basename,如下:

    [root@ryan shelltest]# basename /root/linux/shelltest/fortest.sh
    fortest.sh

    得到目录名,使用 dirname,如下:

    [root@ryan shelltest]# dirname /root/linux/shelltest/fortest.sh
    /root/linux/shelltest

    2.7 执行 Shell

    有两种方式可以执行 Shell,如下:

    第一种:

    sh filename.sh

    如果想调试你的脚本,bash给我们提供了两个选项:-v-x,如下:

    [root@ryan shelltest]# cat iftest.sh
    #! /bin/bash
    ## This shell script is used for testing if
    echo "file name $(basename $0)"
    echo "Hello $1"
    echo "Hello $*"
    echo "Args count: $#"
    argscount=$#
    if [ $argscount -eq 3 ];
    then
    echo 'args count is correct'
    elif [ $argscount -gt 3 ];
    then
    echo 'args count is more than 3'
    else
    echo 'args count is less than 3'
    fi

    如果我们想逐行详细地查看脚本的内容,可以使用 -v 选项。

    [root@ryan shelltest]# sh -v iftest.sh 1 3 a
    #! /bin/bash
    ## This shell script is used for testing if
    echo "file name $(basename $0)"
    file name iftest.sh
    echo "Hello $1"
    Hello 1
    echo "Hello $*"
    Hello 1 3 a
    echo "Args count: $#"
    Args count: 3
    argscount=$#
    if [ $argscount -eq 3 ];
    then
    echo 'args count is correct'
    elif [ $argscount -gt 3 ];
    then
    echo 'args count is more than 3'
    else
    echo 'args count is less than 3'
    fi
    args count is correct

    更常用的是 -x 选项,它们在执行时显示命令。当我们决定选择分支的时候,更加实用。

    [root@ryan shelltest]# sh -x iftest.sh 1 3 a
    ++ basename iftest.sh
    + echo 'file name iftest.sh'
    file name iftest.sh
    + echo 'Hello 1'
    Hello 1
    + echo 'Hello 1 3 a'
    Hello 1 3 a
    + echo 'Args count: 3'
    Args count: 3
    + argscount=3
    + '[' 3 -eq 3 ']'
    + echo 'args count is correct'
    args count is correct

    第二种:

    ./filename.sh(需要有执行权限,所以一般要先授予 x 权限)

    三、shell 运算符

    3.1 算数运算符

    原生 bash 不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr。下面使用 expr 进行;  expr 是一款表达式计算工具,使用它可以完成表达式的求值操作;

    3.2 关系运算符

    只支持数字,不支持字符串,除非字符串的值是数字。常见的有:

    也可以直接使用符号比较,但要同时使用双括号,如下:

    < 小于(需要双括号) (( "$a" < "$b" ))

    <= 小于等于(...) (( "$a" <= "$b" ))

    > 大于(...) (( "$a" > "$b" ))

    >= 大于等于(...) (( "$a" >= "$b" ))

    3.3 布尔运算符

    -o(--or,也可以用 [ $a -lt 20 ] || [ $b -gt 100 ]),-a(--and,也可以用 [ $a -lt 20 ] && [ $b -gt 100 ])

    3.4 字符串运算符

    常用的有 -z,判断变量的值是否存在,不存在返回 true,存在则返回 false。

    3.5 文件测试运算符

    常用的有 -e(--exist,判断文件或目录是否存在),-d(--directory,判断是否目录已经是否存在),-f(--file,判断是否普通文件已经是否存在)

    四、Shell 中的流程控制

    4.1 if 条件选择

    [root@ryan shelltest]# cat iftest.sh
    #! /bin/bash
    ## This shell script is used for testing if
    echo "file name $(basename $0)"
    echo "Hello $1"
    echo "Hello $*"
    echo "Args count: $#"
    argscount=$#
    if [ $argscount -eq 3 ];
    then
    echo 'args count is correct'
    elif [ $argscount -gt 3 ];
    then
    echo 'args count is more than 3'
    else
    echo 'args count is less than 3'
    fi

    运行如下:

    [root@ryan shelltest]# sh iftest.sh 3 5 a
    file name iftest.sh
    Hello 3
    Hello 3 5 a
    Args count: 3
    args count is correct
    [root@ryan shelltest]# sh iftest.sh 3 5
    file name iftest.sh
    Hello 3
    Hello 3 5
    Args count: 2
    args count is less than 3
    [root@ryan shelltest]# sh iftest.sh 3 5 a b
    file name iftest.sh
    Hello 3
    Hello 3 5 a b
    Args count: 4
    args count is more than 3

    4.2 case 条件选择

    [root@ryan shelltest]# cat casetest.sh
    #!/bin/bash
    ## This shell script is used for testing case
    read -p "Input a number:" n
    a=$[$n%2]
    case $a in
    1)
    echo "The number is odd."
    ;;
    0)
    echo "The number is even."
    ;;
    *)
    echo "It's not a number!"
    ;;
    esac

    运行如下:

    [root@ryan shelltest]# sh casetest.sh
    Input a number:4
    The number is even.
    [root@ryan shelltest]# sh casetest.sh
    Input a number:5
    The number is odd.

    4.3 while 循环

    [root@ryan shelltest]# cat whiletest.sh
    #!/bin/bash
    ## This shell script is used for testing while
    a=5
    while [ "$a" -ge "1" ]; do
    echo $a
    a=$[$a-1]
    done

    运行如下:

    [root@ryan shelltest]# sh whiletest.sh
    5
    4
    3
    2
    1

    4.4 for 循环

    [root@ryan shelltest]# cat fortest.sh
    #!/bin/bash
    ## This shell script is used for testing for

    for file in `ls /root/linux/shelltest`;
    do
    ls -ld /root/linux/shelltest/$file
    done

    运行如下:

    [root@ryan shelltest]# sh fortest.sh
    -rwxr-xr-x 1 root root 233 Apr 14 17:33 /root/linux/shelltest/casetest.sh
    -rw-r--r-- 1 root root 18 Apr 13 20:49 /root/linux/shelltest/field.properties
    -rwxr-xr-x 1 root root 141 Apr 14 17:40 /root/linux/shelltest/fortest.sh
    -rwxr-xr-x 1 root root 211 Apr 13 20:48 /root/linux/shelltest/funcomp.sh
    -rwxr-xr-x 1 root root 235 Apr 13 20:47 /root/linux/shelltest/funtest.sh
    -rwxr-xr-x 1 root root 321 Apr 13 20:46 /root/linux/shelltest/iftest.sh
    -rwxr-xr-x 1 root root 101 Apr 14 14:37 /root/linux/shelltest/readtest.sh
    -rwxr-xr-x 1 root root 113 Apr 13 20:46 /root/linux/shelltest/whiletest.sh

    4.5 引入其他 Shell

    方法一:使用 .

    #!/bin/bash
    . firstshell.sh
    echo 'your are in second file'

    方法二:使用 source

    #!/bin/bash
    source firstshell.sh
    echo 'your are in second file'

    4.6 Shell 中的中断和继续

    break,用于循环中,表示退出该层循环到上一层;

    continue,用于循环中,表示结束本次循环,开始下次循环;

    exit,用在任何地方,表示退出 shell 脚本;

    return,用在函数中,表示返回,退出函数;

    这几个命令与 C、Java 等语言中对应的关键字的作用一样。

    4.7 命令 seq

    seq - print a sequence of numbers,用于产生从某个数到另外一个数之间的所有整数。

    语法格式为:

    seq [选项] 尾数

    seq [选项] 首数 尾数

    seq [选项] 首数 增量 尾数

    常用选项为:

    -f, --format=格式 使用 printf 样式的浮点格式;

    -s, --separator=字符串 使用指定字符串分隔数字(默认使用: );

    -w, --equal-width 在列前添加 0 使得宽度相同;

    [root@ryan shelltest]# seq 8
    1
    2
    3
    4
    5
    6
    7
    8

    [root@ryan shelltest]# seq 3 8
    3
    4
    5
    6
    7
    8

    [root@ryan shelltest]# seq 3 2 8
    3
    5
    7

    此处的 2 为增量,也被称为步长。

    shell 示例

    从 top 命令中提取出 time,cpu 百分比和使用的内存容量三种数据到三个不同的文本中,然后进行合并。

    #! /bin/bash
    ## extract_time_cpu_memory.sh filename
    ## Extract the time, cpu and memory data from the top output file
    ## moonxy 2018-06-14
    
    filename=$1
    if [ -z "${filename}" ]
    then
    filename=/tmp/top.out
    echo "default top output file name is : $filename"
    fi
    
    if [ ! -e "${filename}" ]
    then
    echo "Cann't find top output file : $filename, please check it"
    exit 2
    fi
    echo "top output file is : $filename"
    
    ## Extract time data from the top output file
    cat ${filename} | grep "top - " | cut -d ',' -f 1 | awk '{print $3}' > /tmp/top_time.out
    
    ## Extract cpu data from the top output file
    cat ${filename} | grep "%Cpu(s)" | cut -d ',' -f 1 | awk '{print $2}' > /tmp/top_cpu.out
    
    ## Extract memeory data from the top output file
    cat ${filename} | grep "KiB Mem" | cut -d ',' -f 3 | awk '{print $1}' > /tmp/top_memory.out
    
    ## Add the time-cpu table head
    echo 'Time,Cpu(%)' > /tmp/time_cpu_memory.out
    
    ## Merge the data by one column mapping one column
    paste -d',' /tmp/top_time.out /tmp/top_cpu.out >> /tmp/time_cpu_memory.out
    
    ## Append five lines for the result
    echo >> /tmp/time_cpu_memory.out
    echo >> /tmp/time_cpu_memory.out
    echo >> /tmp/time_cpu_memory.out
    echo >> /tmp/time_cpu_memory.out
    echo >> /tmp/time_cpu_memory.out
    
    ## Add the time-memory table head
    echo 'Time,Memory(Used KiB)' >> /tmp/time_cpu_memory.out
    
    ## Append and then Merge the data by one column mapping one column
    paste -d',' /tmp/top_time.out /tmp/top_memory.out >> /tmp/time_cpu_memory.out
    
    echo 'result file name is : /tmp/time_cpu_memory.out'
    exit 0

    注意:

    1. 执行 shell 脚本时,事实上是会新开一个 shell 进程,然后逐行执行你的脚本,上面使用 exit 只是退出这个新开的 shell 进程,并不会影响系统原有 shell 环境。

    2. return 仅能用于函数中或者使用 source a1.sh(或 . a1.sh)中使用,不能直接用于脚本中。

    3. 追加空白行可使用:echo >> /tmp/time_cpu_uatdb.out

  • 相关阅读:
    多线程原理——随机打印结果
    微信小程序自定义组件传递参数
    微信小程序添加自定义组件
    mysql 多表查询内连接
    mysql 创建增删改查
    Python爬虫入门七之正则表达式
    Python爬虫入门六之Cookie的使用
    Python爬虫入门五之URLError异常处理
    Python爬虫入门四之Urllib库的高级用法
    Python爬虫入门二之爬虫基础了解
  • 原文地址:https://www.cnblogs.com/cnjavahome/p/8831612.html
Copyright © 2020-2023  润新知