zoukankan      html  css  js  c++  java
  • shell 编程 && bash 简介(shell 变量、shell操作环境、数据流重导向、管线命令、shell script)

    如何学习一门编程语言 

    1. 数据类型

    2. 运算符

    3. 关键字

    1 认识BASH 这个shell

    linux是操作系统核心,用户通过shell与核心进行沟通,达到我们想要的目的。硬件、核心、用户之间的关系:

    原理:所谓Shell程序,实际上是提供用户操作系统的一个接口,用户可以通过shell程序操作其他应用程序(eg. ls,chown,etc.),让这些应用程序可以呼叫内核来完成工作。Bash是Linux系统下的其中一种Shell程序。当前系统支持哪些Shell程序,可查看/etc/shells配置文件;查看用户配置使用的哪种shell,可查看/etc/passwd配置文件。

    bash:The Bourne Again Shell。

    shell:接口程序,是一个命令语言解释器,拥有内建的命令集。

    1.1 为何要学文字接口的shell

    1. Shell操作方式一致,可一法通、万法通;
    2. 远程管理;
    3. 主机管理及shell编程;

    1.2 bash shell的功能

    //历史查看,在[~/.bash_history]中记录前一次登入以前所执行过的指令,本次执行会暂存在内存中,成功注销后,才会记录到bash_history当中。
    history
    
    //命令补全功能:tab
    tab
    
    //命令别名,自定义设定别名,比如alias lm='ls -al'
    alias lm='ls -al'
    
    //通配符*
    ls -l /user/bin/X*  //查看在/usr/bin底下有多少以X为开头的文件

    1.3 bash shell的内建命令:type

    //type内建命令,type [-tpa] name,选项与参数
     -t:file表示为外部指令;alias 表示命令别名所设定的名称;builtin 表示bash内建的命令
     -p:name为外部指令,才会显示完整文件名
     -a:PATH变量定义路径中,将所有含name指令都列出来,包含alias
    eg:
    //查看一下pwd这个指令是否为bash内建,列出主要使用情况
    [wendy@cs011 ~]$ type pwd  //内建命令
    pwd is a shell builtin
    [wendy@cs011 ~]$ type -a pwd
    pwd is a shell builtin
    pwd is /usr/bin/pwd
    [wendy@cs011 ~]$ type -t pwd  //内建命令,列出执行时的情况
    builtin
    [wendy@cs011 ~]$ type ls
    ls is aliased to `ls --color=auto`
    [wendy@cs011 ~]$ type -a ls
    ls is aliased to `ls --color=auto`  //先使用alias
    ls is /usr/bin/ls                         //找到外部命令在bin/ls
    [wendy@cs011 ~]$ type -t ls  //别名,列出执行时的情况
    alias

    2 shell的变量功能

    变量:让某一个特定字符串代表不固定的内容。即变量就是以一组文字或符号等,来取代一些设定或者一串保留的数据。比如y=ax+b,y就是变量,ax+b是变量的内容。

    取用变量:echo $变量名,比如:echo $PATH 或 echo ${PATH}

    变量的有效范围:比如export后的变量,称为环境变量。环境变量可以被子程序所引用,但其他的自定义变量就不会存在于子程序中。全局变量 = 环境变量;自定义变数 = 局部变量

    • 当启动一个shell,操作系统会分配一记忆区块给shell使用,内存内的变量可以让子程序取用。
    • 父程序利用export功能,可以让自定义变量的内容写入到记忆区块中。
    • 当加载另一个shell时,子shell可以将父shell的环境变量所在的记忆区块导入自己的环境变量区块中。

    Bash的变量分为2种:环境变量(可分为系统级别或用户级别)、普通变量。
    普通变量即用户自定义的变量,变量的设定规则如下:

    • 1.变量与变量内容以一个等号=来连接,比如[ myname=VBird ]
    • 2.等号两边不能有空格;
    • 3.变量名称只能是英文字母与数字,且必须以英文字母开头;
    • 4.变量获取使用,可以通过$var或者${var}读取2种写法;
    • 5.变量内容若有空格符,可使用单引号或者双引号将变量内容结合在一起;

    A.单/双引号的区别在于:双引号内的特殊字符如$, 反引号等,可以保留原本特性;而单引号内的特殊字符则仅作为一般字符(纯文本);

    //双引号内的特殊字符如$等,可以保有原本的属性
    [wendy@cs011 ~]$ var="lang is $LANG"
    [wendy@cs011 ~]$ echo $var
    lang is en_US.UTF-8
    [wendy@cs011 ~]$ var='lang is $LANG'
    [wendy@cs011 ~]$ echo $var
    lang is $LANG

    B.单/双引号使用规则是:

        • 1)双引号之间可有成对双引号,也可有成对单引号,当内外均是双引号时,内部双引号之间不能有空格 ;
        • 2)单引号之间可有成对双引号,也可有成对单引号,当内外均是单引号时,内部单引号之间不能有空格;
        • 3)双引号内可有单个单引号不能有单个双引号,除非以转移字符转义内部双引号;
        • 4)单引号内可有单个双引号,不能有单个单引号,即使转义内部单引号也不行;
    • 6.可以用转义字符将特殊符号如ENTER, $, \, 空格等变成一般字符;
    • 7.如果在一串指令中,还需要其他指令提供的信息,可以使用反单引号【ESC键正下方】或者$()来实现;
    [wendy@cs011 ~]$ v=$(uname -r)
    [wendy@cs011 ~]$ echo $v
    3.10.0-862.2.3.el7.x86_64
    [wendy@cs011 ~]$ v1=`uname -r` //``这个是tab键上面的那个顿点
    [wendy@cs011 ~]$ echo $v1
    3.10.0-862.2.3.el7.x86_64
    • 8.如果变量需要在其他子程序中使用,可以用export命令将其变成环境变量;
    //该变量在其他子程序执行,需要用export来使变量变成环境变量
    export PATH
    
    //变量为扩增变量,可用"$变量名称" 或${变量}累加内容
    [wendy@cs011 develop]$ version=1
    [wendy@cs011 develop]$ echo $version
    1
    [wendy@cs011 develop]$ version="$version":/第二个参数
    [wendy@cs011 develop]$ echo $version
    1:/第二个参数
    [wendy@cs011 develop]$ version=$version:/第三个参数
    [wendy@cs011 develop]$ echo $version
    1:/第二个参数:/第三个参数
    [wendy@cs011 develop]$ version=$version:/第四个参数
    [wendy@cs011 develop]$ echo $version
    1:/第二个参数:/第三个参数:/第四个参数
    • 9.取消自定义变量命令unset;
    • 10.交互获取变量命令read;
    • 11.关于bash的补充说明:环境变量可理解为bash的全局变量,在用户取得bash时初始化并赋值。环境变量的初始化配置文件及读取顺序如下:

    a.变量类型默认为“字符串”,可用declare申明变量类型

    b.bash环境中的数值运算,预设的精度仅能达到整数形态;

    • 12.环境变量查看命令env;环境变量及自定义变量查看命令set。
    //列出目前的shell环境下的所有环境变量与其内容
    env
    //set观察所有变量(含环境变量与自定义变量)
    set
    ps:env 与set 区别:该变量是否会被子程序所继续引用
    //export:自定义变量转成环境变量,可以使用declare
    export  //显示所有的环境变量

    2.1 影响显示结果的语系变量(locale)

    //locale -a :后面可以不加任何选项与参数
    [wendy@cs011 ~]$ locale
    LANG=en_US.UTF-8
    LC_CTYPE="en_US.UTF-8"

    2.2 变量键盘读取、数组与宣告:read,array,declare

    //read :读取来自键盘输入的变量。read [-pt] variable
     -p:后面可以接提示字符
     -t:后面可以接等待的秒数
    eg:
    [wendy@cs011 ~]$ read atest
    aaaa    //等待输入,键盘输入内容
    [wendy@cs011 ~]$ echo $atest
    aaaa
    
    [wendy@cs011 ~]$ read -p atest:
    atest:wendy
    [wendy@cs011 ~]$ echo $atest
    aaaa
    
    //declare/typeset:宣告变量的类型,declare [-aixr] variable
     -a:变量定义成为数组类型(array)
     -i:变量成为整数数字类型(integer)
     -x:export一样,变成为环境变量
     -r:变量设定为readonly类型,该变量不能更改,也不能unset。需要注销在登入才能复原该变量类型
    
    eg:
    [wendy@cs011 ~]$ declare -i sum=10+20   //-i 定义变量sum为integer
    [wendy@cs011 ~]$ echo $sum
    30
    
    [wendy@cs011 ~]$ declare -x sum   //-x 定义变量sum为环境变量
    [wendy@cs011 ~]$ export | grep sum
    declare -ix sum="30"
    
    [wendy@cs011 ~]$ declare -r sum  //-r 定义变量sum为只读
    [wendy@cs011 ~]$ sum=10+20+30
    -bash: sum: readonly variable
    
    //让sum变成非环境变量的自定义变量
    [wendy@cs011 ~]$ declare +x sum  //+x 取消变量为自定义变量
    [wendy@cs011 ~]$ declare -p sum
    declare -ir sum="30"
    //数组变量类型
    [wendy@cs011 ~]$ var[1]="small min"
    [wendy@cs011 ~]$ var[2]="big min"
    [wendy@cs011 ~]$ var[3]="nice min"
    [wendy@cs011 ~]$ echo "${var[1]},${var[2]},${var[3]}"
    small min,big min,nice min

     

    3 命令别名与历史命令

    //命令别名设定:alias, 别名='指令 选项....'
    alias lm='ls -al | more'
    
    //取消命令别名unalias
    unalias lm
    
    //history[n][-c]   或history [-raw] hisfiles
     n:数字
     -c:将目前的shell中的所有history内容全部消除
     -a:目前新增的history指令新增入histfiles,若没有加hisfiles,则预设写入~/.bash_history
     -r:将histfiles的内容读到目前这个shell的history记忆
     -w:将目前的history记忆内容写入histfiles中
    
    eg:
    [wendy@cs011 ~]$ history 3
      999  alias
     1000  clear
     1001  history 3
    [wendy@cs011 ~]$ history -w
    [wendy@cs011 ~]$ echo $HISTSIZE
    1000
    [wendy@cs011 ~]$ history 3
     1002  history -w
     1003  echo $HISTSIZE
     1004  history 3

    4 bash shell 的操作环境

    4.1 路径与指令搜索顺序

    • 1.以相对/绝对路径执行指令,例如[/bin/ls]或[./ls]
    • 2.由alias找到该指令来执行
    • 3.由bash内建的builtin指令来执行
    • 4.透过$PATH这个变量的顺序搜寻到的第一个指令来执行
    //指令执行顺序
    [wendy@cs011 ~]$ alias echo='echo -n'
    [wendy@cs011 ~]$ type -a echo
    echo is aliased to `echo -n`
    echo is a shell builtin
    echo is /usr/bin/echo

    4.2 bash的进站与欢迎讯息

    // bash进站与欢迎讯息:/etc/issue、/etc/motd
    [wendy@cs011 ~]$ cat /etc/issue
    S
    Kernel 
     on an m 

    4.3 环境配置文件

    环境配置文件:login、non-login shell、/etc/profile、~/.bash_profile,source,~/.bashrc

    //bash的环境配置文件:login、non-login shell、/etc/profile、~/.bash_profile,source,~/.bashrc
    //login shell读取的配置文件
    1、/etc/profile:login shell才会读,这是系统整体的设定,最好不要修改这个档案
    2、~/.bash_profile或~/.bash_login或~/.profile:属于使用者个人设定,你要改自己的数据,依次执行

    login shell的配置文件读取流程:实现的方向是主线流程 ,虚线的方向则是被呼叫的配置文件。在centos的login shell环境下,最终被读取的配置文件是[~/.bashrc]这个文件。

    //source:读入环境配置文件的指令,/etc/profile与~/.bash_profile都是在取得login shell的时候才会读取的配置文件。
    //source 配置文件档名,利用source或小数点(.)都可以将配置文件的内容读进来目前的shell环境中。
    
    eg://将home目录的~/.bashrc的设定读入目前的bash环境中,有如下2种方式。
    [wendy@cs011 ~]$ source ~/.bashrc
    [wendy@cs011 ~]$ . ~/.bashrc
    //non-login shell情况下,bash配置文件仅会读~/.bashrc
    [wendy@cs011 ~]$ cat ~/.bashrc
    # .bashrc
    # Source global definitions //整体的环境设定
    if [ -f /etc/bashrc ]; then
            . /etc/bashrc
    fi
    # Uncomment the following line if you don't like systemctl's auto-paging feature:
    # export SYSTEMD_PAGER=
    # User specific aliases and functions
    export NVM_DIR="$HOME/.nvm"
    [ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"  # This loads nvm
    [ -s "$NVM_DIR/bash_completion" ] && . "$NVM_DIR/bash_completion"  # This loads nvm bash_completion

     4.4 终端机的环境设定

    //终端机的环境设定:stty,set 。可以在tty1~tty6这六个文字接口的终端机环境中登入。syyt [-a]
     -a :将目前所有的stty参数列出来
    
    eg:
    [wendy@cs011 ~]$ stty -a
    speed 38400 baud; rows 43; columns 115; line = 0;
    intr = ^C; quit = ^; erase = ^H; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>; swtch = <undef>; start = ^Q;
    stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0;
    -parenb -parodd -cmspar cs8 -hupcl -cstopb cread -clocal -crtscts
    -ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc -ixany -imaxbel -iutf8
    opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
    isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke
    
    //set [-uvCHhmBx]
     -u:默认不启用,启用时,未设定变量时,会显示错误信息
     -v:默认不启用,启用后,讯息被输出前,会先显示讯息的原始内容
     -x:默认不启用,启用后,在指令被执行前,会显示指令内容
     -h:默认启用,与历史命令有关
     -H:默认启用,与历史命令有关
     -m:默认启用,与工作管理有关
     -B:默认启用,与刮号[]的作用有关
     -C:默认不启用,若使用>等,则若文件存在时,该文件不会被覆盖
    
    //$- :变量内容就是set的所有设定,bash预设是himBH
    [wendy@cs011 ~]$ echo $-
    himBH
    
    [wendy@cs011 ~]$ set -u
    [wendy@cs011 ~]$ echo $vbirding
    -bash: vbirding: unbound variable
    
    [wendy@cs011 ~]$ set -x
    ++ printf '33]0;%s@%s:%s07' wendy cs011 '~'
    
    [wendy@cs011 ~]$ echo $HOME
    + echo /home/wendy 
    /home/wendy 
    ++ printf '33]0;%s@%s:%s07' wendy cs011 '~' 

    常用的快捷键:

    Ctr + C

    终止当前任务

    Ctr + Z

    暂停当前任务

    Ctr + S

    暂停屏幕输出

    Ctr + Q

    回复屏幕输出

    Ctr + U

    删除提示符之前内容

    Ctr + K

    删除提示符之后内容

    4.5 通配符与特殊符号

    特殊符号:

    通配符:

    eg:
    //找出/etc/底下文件名刚好是5个字母的文件名
    [wendy@cs011 ~]$ ll -d /etc/?????
    drwxr-x---. 3 root root 4096 Mar 20  2019 /etc/audit
    
    //找出/etc/底下以cron为开头的文件名
    [wendy@cs011 ~]$ ll -d /etc/cron*
    drwxr-xr-x. 2 root root 4096 Mar 20  2019 /etc/cron.daily
    
    //找出/etc/底下文件名含有数字的文件名
    [wendy@cs011 ~]$ ll -d /etc/*[0-9]*
    -rw-r--r--  1 root root  228 Oct 18  2017 /etc/m2.conf
    
    //找出/etc/底下文件名开头不为大写字母开头的文件名
    [wendy@cs011 ~]$ ll -d /etc/[^A-Z]*
    -rwxrwxrwx  1 root root 1789280 Mar 20  2019 /etc/aayx

    5 数据流重导向(Redirection)

    数据流重导向:将某个指令执行后出现在屏幕上的数据。

    • 标准输出:指的是指令执行所回传的正确的讯息。
    • 标准错误输出:指令执行失败后,所回传的错误讯息。

    指令执行过程的数据传输情况示意图:

    数据流重导向可以将standard output(简称stdout)与standard error output(简称stderr)分别传送所用的特殊字符如下:

    • 1.标准输入(stdin):代码为0,使用< 或 << ;
    • 2.标准输出(stdout):代码为1,使用> 或>>;
    • 3.标准错误输出(stderr):代码为2,使用2> 或2>>;
    • 4./dev/null:垃圾桶黑洞装置与特殊写法
    //用cat直接将输入的讯息输出到catfile中,且当由键盘输入eof时,该次输入就结束
    cat > catfile << "eof"
    
    eg:
    [wendy@cs011 develop]$ cat >test.txt <<"eof"
    > wendy001
    > wendy002
    > wendy003
    > eof   //输入这关键字,立刻就结束而不需要输入ctrl+d
    [wendy@cs011 develop]$ vi test.txt
    [wendy@cs011 develop]$ cat >test.txt <<"eof"
    > wendy004
    > wendy005
    > wendy006
    > eof
    [wendy@cs011 develop]$ vi test.txt
    [wendy@cs011 develop]$ cat >>test.txt <<"eof"
    > wendy001
    > wendy002
    > wendy003
    > eof

    命令执行的判断依据:;.&& ||

    //cmd;cmd (不考虑指令相关性的连续指令下达),比如先执行两次sync同步化写入磁盘后才shutdown
    sync;sync;shutdown -h now
    
    // $?(指令回传值)  与 ## 或 ||
    $? =0,若前一个指令执行的结果为正确,在linux底下会回传一个 $?=0 的值
    
    // &&
    ls /tmp/abc && touch /tmp/abc/hehe //ls显示找不到对应的目录,touch还未执行
    
    // ||
    ls /tmp/abc || mkdir /tmp/abc  // 不存在该文件
    ll /tmp/abc //上面指令执行mkdir命令

    指令依序执行的关系示意图:

    • 1.上方线段为不存在/tmp/abc,回传$?!=0,因为||执行mkdir,回传$?=0,又遇到&&,执行touch
    • 2.下方线段为存在/tmp/abc,回传$?=0,因为||,所以不执行mkdir,$?=0往后继续回传,因为又遇到&&,执行touch

    6 管线命令(pipe)

    管线命令 | 仅能处理经由前面一个指令传来的正确信息,也就是stdout的信息,对于stderr并没有直接处理的能力。

    管线命令的处理示意图:在每个管线后面接的第一个数据必定是指令,而且这个指令必须要能够接受stdin的数据才行,称为管线命令。

    比如less,more,head,tail等都是可以接收stdin的管线命令,至于例如ls,cp,mv等就不是管线命令。

    6.1 截取命令:cut、grep

    截取命令:cut,grep。就是将一段数据经过分析后,取出想要的,或者经由分析关键词,取得我们所想要的那一行。截取信息通常是针对一行一行来分析的。

    //cut的用途:在于将同一行里面的数据进行分解,即将一行讯息当中,取出某部分我们想要的。
    //cut用于有特定分隔字符,cut -d '分隔字符' -f fields 
     -d:后面接分隔字符,与-f一起使用
     -f:依据-d的分隔字符将一段讯息分割成为数段,用-f取出第几段
     -c:以字符的单位取出固定字符区间,同时可以处理具有格式的输出数据,比如第12-20的字符,就是:cut -c 12-20
    //cut -c 字符区间
    
    eg:
    [wendy@cs011 jdk]$ echo $PATH
    /opt/wendy/local/jdk/jdk1.8.0_152/bin:/home/wendy/.nvm/versions/node/v10.18.1/bin:/usr/local/bin:/usr/bin:/usr/local/sbin
    [wendy@cs011 jdk]$ echo $PATH | cut -d ':' -f 4   //以:作为分隔符,列出第四的内容
    /usr/bin
    [wendy@cs011 jdk]$ echo $PATH | cut -d ':' -f 4,5  //以:作为分隔符,列出第四、第五的内容
    /usr/bin:/usr/local/sbin 
    //grep:分析一行讯息,grep [-acinv][--color=auto]'搜寻字符串' filename
     -a:将binary文件以test文件的方式搜寻数据
     -c:计算找到'搜寻字符串'的次数
     -i:忽略大小写的不同,所以大小写视为相同
     -n:顺便输出行号
     -v:反向选择
     --color=auto:可以将找到的关键词部分加上颜色的显示.
    eg:
    last | grep 'root'| cut -d '' -f1  //在last的输出讯息中,只要有root就取出,并且以空为分隔符,仅取第一栏。在取出root之后,利用上个指令cut的处理,就能够仅取得第一栏。
    last | grep -v 'root'  //只要没有root的就取出
    last | grep 'root' //将last当中,有出现root的那一行取出来 

    6.2 排序命令:sort、uniq、wc

    场景:计算一次数据里头的相同型态的数据总数,使用last可以查得这个月份有登入主机者的身份。

    • sort:排序,根据不同数据型态来排序,比如数字与文字的排序,此外排序的字符与语系的编码有关。
    • uniq:排序完成之后,想要将重复的资料仅列出一个显示。
    • wc:统计/etc/man.config文件里面有多少字、多少行、多少字符。
    //排序命令:sort,wc,uniq。sort [-fbMnrtuk][file or stdin],sort进行排序,可以根据不同的数据型态来排序,比如数字与文字的排序。
     -f:忽略大小写的差异,例如A与a 视为编码相同
     -b:忽略最前面的空格符部分
     -M:以月份的名字来排序,例如JAN,DEC等等的排序方法
     -n:使用纯数字进行排序(默认是以文字型态来排序的)
     -r:反向排序
     -u:就是uniq,相同的数据中,仅出现一行代表
     -t:分隔符,预设是用tab键来分隔
     -k:以哪个区间(field)来进行排序
    eg:
    //sort排序,个人账号都记录在/etc/passwd下,并将账号进行排序,默认是以第一个数据来排序,从a-z进行显示
    [wendy@cs011 jdk]$ cat /etc/passwd |sort
    abrt:x:173:173::/etc/abrt:/sbin/nologin
    adm:x:3:4:adm:/var/adm:/sbin/nologin
    bin:x:1:1:bin:/bin:/sbin/nologin
    chrony:x:996:994::/var/lib/chrony:/sbin/nologin
    
    //sort排序,在/etc/passwd内容是以:来分隔的,以第三栏来排序
    [wendy@cs011 jdk]$ cat /etc/passwd |sort -t ':' -k 3
    root:x:0:0:root:/root:/bin/bash
    haishu:x:1000:1000::/home/wendy:/bin/bash
    operator:x:11:0:operator:/root:/sbin/nologin
    bin:x:1:1:bin:/bin:/sbin/nologin
    
    //uniq [-ic],排序完成,将重复的资料仅列出一个显示.-c表示reboot登录有12次,root登录有41次。wtmp与空白都是last的默认字符,那两个可以忽略。
     -i:忽略大小写字符的不同
     -c:进行计数
    [wendy@cs011 jdk]$ last |cut -d ' ' -f1 | sort | uniq -c
    1
    12 reboot
    41 root
    1 wtmp
    
    //wc [-lwm],/etc/profile里面到底有多少行、字数、字符数
     -l:仅列出行
     -w:列出多少字
     -m:多少字符
    [wendy@cs011 jdk]$ cat /etc/profile | wc
         80     261    1903

    6.3 双向重导向:tee

    tee:将数据流的处理过程中的某段讯息存下来。tee会同时将数据流分送到文件与屏幕里去。输出到屏幕的,就是stdout。

    tee的工作流程示意图:

    //tee:同时将数据流分送到文件去与屏幕(screen),而输出到屏幕的,其实就是stdout
    //tee [-a] file
     -a:以累加(append)的方式,将数据加入file当中
    last | tee last.list | cut -d " " -f1  //让我们将last的输出存一份到last.list文件中
    ls -l /home | tee ~/homefile |more //将ls的数据存一份到~/homefile,同时屏幕也有输出讯息。
    ls -l / | tee -a ~/homefile |more //tee后接的文件会被覆盖,若加上-a 这个选项则能将讯息累加。

    6.4 字符转换命令:tr、col、join、paste、expand

    • tr:可以用来删除一段信息当中的文字,或者是进行文字信息的替换。
    • col:用来简单的处理将tab键取代称为空格键。
    • join:处理两个文件之间的数据,主要是处理在两个文件当中,有相同数据的那一行,才将他加在一起。
    • paste:必须要比对两个文件的数据相关性。paste就直接将两行贴在一起,且中间以tab键隔开。
    //字符转换命令:tr,col,join,paste,expand
    //tr 可以用来删除一段讯息当中的文字,或者是进行文字讯息的替换,tr [-ds] SET1 ...
     -d:删除讯息当中的[SET1]这个字符串
     -s:取代掉重复的字符
    
    eg:
    //将last输出的讯息中,所有的小写变成大写字符
    [wendy@cs011 jdk]$ last | tr '[a-z]' '[A-Z]' 
     
    //将/etc/passwd输出的讯息中,将冒号(:)删除
    源文件显示:
    [wendy@cs011 ~]$ cat /etc/passwd root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin [wendy@cs011 ~]$ cat /etc/passwd | tr -d ':' rootx00root/root/bin/bash binx11bin/bin/sbin/nologin daemonx22daemon/sbin/sbin/nologin //col [-xb] -x:将tab键转换成对等的空格键 -b:在文字内有反斜杠(/)时,仅保留反斜杠最后接的那个字符 cat /etc/profile | col -x | cat -A |more 
    //join [-ti12] file1 file2 
     -t:join默认以空格符分隔数据,并且比对[第一个字段]的数据,如果2个文件相同,则将两笔数据联成一行,且第一个字段放在第一个
     -i:忽略大小写的差异
     -1:数字的1,代表第一个文件要用那个字段来分析
     -2:代表第二个档案要用那个字段来分析
    
    test.txt:001:wendy:004、002:wendy:005、003:wendy:006、004:wendy:001、005:wendy:002、006:wendy:003
    test001.txt:001:002、002:003、003:004、004:005
    //将test.txt与test001.txt相关数据整合成一栏,结果显示为:
    [wendy@cs011 develop]$ head -n 10 ./test.txt ./test001.txt
    ==> ./test.txt <==
    001:wendy:004
    002:wendy:005
    003:wendy:006
    004:wendy:001
    005:wendy:002
    006:wendy:003
    
    ==> ./test001.txt <==
    001:002
    002:003
    003:004
    004:005
    //join使用之前,你所需要处理的文件应该要事先经过排序处理,将两个文件第一个字段相同者整合成一行,第二个文件的相同字段并不会显示
    [wendy@cs011 develop]$ join -t ':' ./test.txt ./test001.txt
    001:wendy:004:002
    002:wendy:005:003
    003:wendy:006:004
    004:wendy:001:005
    //paste [-d] file1 file2 ,选项与参数
     -d:后面可以接分隔字符,预设以tab来分隔
     -:如果file部分写成-,表示来自stdin的文件
    
    eg:
    //将test.txt与test001.txt同一行贴在一起,同一行中间以tab按键隔开 [wendy@cs011 develop]$ paste test.txt test001.txt
    001:wendy:004 001:002 002:wendy:005 002:003 003:wendy:006 003:004 004:wendy:001 004:005 005:wendy:002 006:wendy:003
    //expand [-t] file,选项要参数。在将tab按键转成空格键
     -t:后面可以接数字,一个tab按键可以用8个空格键取代

    6.5  分割命令:split

    场景:文件太大,导致无法复制,split可以帮你将一个大文件,依据文件大小或行数来分隔,就可以将大文件分割成小文件。

    //split分割命令,split [-bl] file PREFIX
     -b:后面可接文件大小,可加单位,例如b,k,m。
     -l:以行数来进行分割。
     PREFIX:代表前导符的意思,可作为分割文件的前导文字。
    
    eg:
    //分割命令split,那个文件名可以随意取,只要写上前导文件,小文件就会以xxxaa,xxxab,xxxac等方式来建立小文件的。
    [wendy@cs011 develop]$ split -b 30 ./test.txt test.txt
    [wendy@cs011 develop]$ ll -k test.txt*
    -rw-rw-r-- 1 wendy wendy 84 Apr 27 10:55 test.txt
    -rw-rw-r-- 1 wendy wendy 30 Apr 27 11:20 test.txtaa
    -rw-rw-r-- 1 wendy wendy 30 Apr 27 11:20 test.txtab
    -rw-rw-r-- 1 wendy wendy 24 Apr 27 11:20 test.txtac
    
    //将三个上面的三个小文件合成一个文件,文件名为testback
    [wendy@cs011 develop]$ cat test.txta* >> test.txtback
    [wendy@cs011 develop]$ ll
    -rw-rw-r-- 1 wendy wendy 84 Apr 27 10:55 test.txt
    -rw-rw-r-- 1 wendy wendy 30 Apr 27 11:20 test.txtaa
    -rw-rw-r-- 1 wendy wendy 30 Apr 27 11:20 test.txtab
    -rw-rw-r-- 1 wendy wendy 24 Apr 27 11:20 test.txtac
    -rw-rw-r-- 1 wendy wendy 84 Apr 27 11:26 test.txtback

    6.6 参数代换:xargs

    xargs:x是加减乘除的乘号,args则是arguments(参数)。xargs参数产生某个指令的参数。xargs可以读入stdin的数据,并且以空格符或断行字符作为分隔,将stdin的资料分隔成为arguments。

    //xargs [-0epn] command,选项与参数
     -0:输入的stdin含有特殊字符,例如'\,空格键等字符时,这个-0参数还原成一般字符。
     -e: 这个是EOF(end of file ),后面可以接一个字符串,当xargs分析到这个字符串时,就会结束继续工作。
     -n:后面接次数,每次command指令执行时,要使用几个参数。当后面没有参数时,默认是以echo来进行输出。
     -p:在执行每个指令的argument时,都会询问使用者的意思
    
    eg:
    [wendy@cs011 ~]$  cut -d: -f1 < /etc/passwd | sort | xargs echo
    abrt adm bin chrony daemon dbus ftp games gluster haishu halt libstoragemgmt lp mail named nobody ntp operator polkitd postfix root rpc shutdown sshd sync systemd-bus-proxy systemd-network tcpdump tss

    重点:

    • 核心在内存中受保护,需要透过shell 将我们输入的指令与核心沟通
    • 学习shell的原因:一致性;速度快;shell主导
    • 系统合法的shell均写在/etc/shells文件中
    • 用户默认登录取得的shell记录在/etc/passwd的最后一个字段
    • bash功能的主要有:命令修复能力;命令与档案补全功能;命令别名设定功能;工作控制、前景背景控制;程序后脚本;通配符
    • type可以用来找到执行指令为何种类型
    • 变量就是以一组文字或符号等,来取代一些设定或者是一串保留的数据
    • 变量主要有环境变量与自定义变量,或称为全局变量与局部变量,使用env、export可观察环境变量,export可以将自定义变量转成环境变量
    • set可以观察目前bash环境下的所有变量;$?为变量,是前一个指令执行完毕后的回传值,回传值=0表示执行成功
    • locale可以观察语系资料;可用read让用户由键盘输入变量的值,ulimit可用以限制用户使用系统的资源情况
    • bash的配置文件主要分为login shell与non-login shell.login shell主要读取/etc/profile与~/.bash_profile,non-login shell则仅读取~/.bashrc
    • 通配符主要有:*?[]等待
    • 数据流重导向透过>,2>,<之类的符号将输出的信息转到其他文件或装置去
    • 连续命令的下达:&& 、||
    • 管线命令的重点:管线命令仅会处理stdout,对于stderr会予以忽略,同时管线命令必须要能够接受来自前一个指令的数据成为stdin继续处理。
    • 管线命令主要包含:cut、grep、sort、wc、uniq、tee、tr、col、join、paste、expand、split、xargs。

     7 正规表示法与文件格式化处理

      正规表示法[Regular Expression,RE,常规表示法]:处理字符串的方法,以行为单位来进行字符串的处理行为。透过一些特殊字符的排列,用以搜寻/取代/删除一列或多列文字字符串[简单说,正则表示法就是用在字符串的处理上面的一项表达式,是一个字符串处理的标准依据]。比如:vi,sed,awk等等。只要工具程序支持正规表示法,该工具程序就可以用来作为正规表示法的字符串处理之用。

    正规表示法的字符串表示方式依照不同的严谨程度分为:基础正规表示法与延伸正规表示法。

    • 基础正规表示法:处理字符串的一种表示方式,对字符排序有影响的语系数据就会对正规表示法的结果有影响。比如grep.
    • 延伸型正规表示法:除了简单的一组字符串处理之外,还可以作群组的字符串处理。

    常见的正规表示法工具有:grep、sed、awk、vim。printf可以透过一些特殊符号来将数据进行格式化输出,awk可以使用字段为依据,进行数据的重新整理与输出。

    7.1 grep工具

    grep作用:字符串数据比对,将符合用户需要的字符串打印出来。

    grep在数据中查寻一个字符串时,是以"整行"为单位来进行数据的截取。比如一个文件内有10行,其中有2行是你所搜寻的字符串,则将那两行显示在屏幕上,其他丢弃。

    在关键词显示方面,用--color=auto来将关键词部分使用颜色进行显示。

    //grep [-A][-B][--color=auto] '搜寻字符串' filename
     -A:after的意思,除了列出该行外,后续的n行也列出来
     -B:before的意思,除了列出该行外,前面的n行也列出来
     --color=auto 可将正确的那个截取数据列出颜色
    
    eg1:
    //用dmesg列出核心信息,再以grep 找到eth所在行的前2行与后三行也一起进行显示
    dmesg | grep -n -A3 -B2 --color=auto 'eth'
    
    eg2:
    test.txt文件内容:001:wendy:004002:wendy:005003:wendy:006004:wendy:001005:wendy:002006:wendy:003
    
    //1.搜寻特定字符串,比如从test.txt文件当中取得001这个特定字符串
    [wendy@cs011 develop]$ grep -n '001' test.txt
    1:001:wendy:004
    4:004:wendy:001

    //2.反向选择,比如从test.txt文件当中,当该行没有'001'这个字符串时才显示在屏幕上
    eg1:
    [wendy@cs011 develop]$ grep -vn '001' test.txt

     显示结果如图

    eg2://反向选择,从test.txt中搜索不包含001的行

    [wendy@cs011 develop]$ grep '[^001]' test.txt 

      显示结果如图:

    //3.利用中括号[]来搜寻集合字符,比如搜索0*:wendy或0*:wendy,*表示随意 //[]里面无论有几个字符,都只代表一个字符

    [haishu@cs011 develop]$ grep -n '0[0-9]:wendy' test.txt

      显示结果如图:

    //4.在g与g之间有2个到3个的o存在的字符串。{n,m}:指的是连续n到m个以上的前一个Re字符。

    [haishu@cs011 develop]$ grep -n 'go{2,3}g' regular_express.txt

    正规表示法与通配符完全不一样,通配符代表的是bash操作接口的一个功能,但正规表示法则是一种字符串处理的表示方式。

    使用grep或其他工具进行正规表示法的字符串比对时,编码问题会有不同的状态,设置LANG等变量设定为C或是en的英文语系,可利用特殊符号[:upper:]来替代编码范围。

    grep与egrep在正规表示法里面常见的两支程序,其中egrep更支持正规表示法的语法。

    grep -v '^$' test.txt | grep -v '^#' //egrep进行简化,透过群组功能|来进行一次搜寻。grep -E = egrep 的写法

    egrep -v '^$ | ^#' test.txt

    基础的正规表示法[grep]:

     

    延伸的正规表示法[egrep]

     

    7.2 sed 工具

    sed是一个管线命令,可以分析stdin等。

    sed功能:数据进行取代、删除、新增、截取特定行等等的功能。 

    // sed [-nefr] [动作],选项与参数说明
     -n:使用安静(silent)模式。在一般sed用法中,所有来自STDIN的数据一般都会被列出屏幕上。
     -e:直接在指令列模式上进行sed的动作编辑。
     -f:直接将sed的动作写在一个文件内,-f filename则可以执行filename内的sed动作
     -r:sed的动作支持的是延伸型正规表示法的语法。(预设是基础正规表示法语法)
     -i:直接修改读取的文件内容,而不是由屏幕输出。
    
    [动作说明]:[n1[,n2]]function
    n1,n2:不一定存在,代表选择进行动作的行数,比如在10-20行之间进行,则[10,20][动作行为]
    
    function有如下参数:
    a:新增,a的后面接字符串,在新行进行显示
    c:替换,接字符串,可以在n1,n2之间替换
    i:插入,接字符串,新行出现
    d:删除
    p:打印,与参数sed -n一起使用
    s:替换,直接替换,比如1,20s/old
    
    eg1:以行为单位的新增/删除功能
    //将etc/passwd的内容列出并且打印行号,请将2~5行删除。
    [wendy@cs011 develop]$ nl /etc/passwd | sed '2,5d'
    //只要删除第2行。
    [wendy@cs011 develop]$ nl /etc/passwd | sed '2d'
    //删除第3行到最后一行,$代表最后一行!
    [wendy@cs011 develop]$ nl /etc/passwd | sed '3,$d'
    
    //新增,在a后面加上的字符串就已将出现在第二行后面。
    [wendy@cs011 develop]$ nl /etc/passwd | sed '2a drink tea'
    //新增,加上的字符串就已将出现在第二行前面,由a改为i即可。
    [wendy@cs011 develop]$ nl /etc/passwd | sed '2i drink tea'
    
    eg2:以行为单位的取代与显示功能
    //将etc/passwd中的第2~5行的内容替换[2,5c]:No 2-5number
    [wendy@cs011 develop]$ nl /etc/passwd | sed '2,5c No 2-5number'
    
    eg3:以行为单位的显示功能
    //列出文件内的第5-7行,sed '5,7p'(5-7行会重复输出),所以一般与-n一起使用
    [wendy@cs011 develop]$ nl /etc/passwd | sed -n '5,7p'
    
    eg4:部分数据的搜寻并取代的功能
    //除了整行的处理模式之外,sed还可以用来行为单位进行部分数据的搜寻并取代的功能
    //sed 's/要被取代的字符串/新的字符串/g'
    [wendy@cs011 develop]$ sbin/ifconfig eth0 | grep 'inet addr' | sed 's/^.*addr://g' |sed 's/Bcast.*$//g'

     7.3 awk工具

    awk:数据处理工具,相较于sed常常作用于一整个行的处理,awk则比较倾向于一行当中分成数个[字段]来处理,即awk不是[以行为一次处理的单位],而[以字段为最小的处理的单位]。

    awk处理流程如下:

    • 1.读入第一行,并将第一行的资料填入$0,$1,$2...等变数当中。$0表示一整行的内容,$1表示第一个参数
    • 2.依据 条件类型 的限制,判断是否需要进行后面的动作
    • 3. 做完所有的动作与条件类型
    • 4. 若还有后续的行数据,则重复1-3的步骤,直到所有的数据都读完为止
    //awk '条件类型1{动作1} 条件类型2{动作2}....' filename  。
    awk主要处理每一行的字段内的数据,而默认的字段的分隔符为空格键或tab键。
    eg1:
    //取出前5行,取出第一个参数和第三个参数,tab键隔开,用print的功能将字段数据列出来
    last -n 5 | awk '{print $1 'tab' $3}'
    eg2:
    //取出前5行,列出每一行的账号($1);列出目前处理的行数(NR变量);该行有多少字段(NF变量)
    last -n 5 | awk '{print $1 "	lines:"NR "	 columes:"NF}'
    
    eg3://逻辑判断,BEGIN关键字
    ///etc/profile当中以冒号来作为字段的分隔,第一个字段是账号,第三个字段是UID
    //需求:查询第三个参数小于10以下的数据,并且仅列出账号与第三栏
    cat /etc/profile | awk 'BEGIN {FS=":"} $3<10 {print $1 "	" $3}'

    awk的逻辑运算字符:

     

     7.4 printf打印

    文件进行一些简单的编排,通过数据流重导向配合底下介绍的printf功能,以及awk指令。

    //格式化打印:printf '打印格式' 实际内容
    a 警告声音输出
     退格键(backspace)
    f 清除屏幕(form feed)
    
     输出新的一行
    
     Enter按键
    	 水平的tab按键
    v 垂直的tab按键
    xNN NN为两位数的数字,可以转换数字成为字符。
    //关于C程序语言内,常见的变数格式
    %ns:n=number;s=string,指的是多少个字符
    %ni:n=number;i=integer,指的是多少整数字数
    %N.nf:n、N=number;f=floating(浮点),如果有小数字数,比如%10.2f表示10个位数,但小数点有2位

    重点:

    • 正规表示法就是处理字符串的方法,以行为单位来进行字符串的处理行为。
    • 正规表示法透过一些特殊字符的辅助,能达到搜索、删除、取代某特定字符串的处理程序。
    • 只要工具程序支持正规表示法,该工具程序就可以用来作为正规表示法的字符串处理之用。
    • 通配符代表的是bash操作接口的一个功能,但正规表示法则是一种字符串处理的表示方式。
    • 使用grep或其他工具进行字符串比对,编码问题会有不同的状态。
    • 基础正规表示法的特殊字符有:*、?、[]、[-]、[^]、^、$。
    • 常见的正规表示法工具:grep、sed、vim。
    • printf可以透过一些特殊符号来讲数据进行格式化输出。
    • awk可以使用字段为依据,进行数据的重新整理与输出。
    • 文件的比对中,可利用diff及cmp进行比对,其中diff及cmp进行比对,其中diff主要用在纯文本文件方面的新旧版本比对。
    • patch指令可以将旧版数据更新到新版。

    8 shell script

    8.1 为什么学习shell script

    shell script 是利用shell的功能所写的一个程序,这个程序是使用纯文本文件,将一些shell的语法与指令(含外部指令)写在里面,搭配正规表示法、管线命令与数据流重导向等功能。

    shell:文字接口底下让我们与系统沟通的一个工具接口。

    shell script的特点:

    • 自动化管理的重要性
    • 追踪与管理系统的重要工作
    • 简单入侵检测功能
    • 连续指令单一化
    • 简易的数据处理
    • 跨平台支持与学习历程较短

    shell script的注意事项:

    • 1.指令的执行时从上而下、从左而右的分析与执行。
    • 2.指令、选项与参数间的多个空白都会被忽略掉。
    • 3.空白行也将被忽略掉,并且tab按键所推开的空白同样视为空格键。
    • 4.如果读取到一个enter符号(CR),就尝试开始执行该行命令。
    • 5.至于如果一行的内容太多,则可以使用[enter]来延伸至下一行。

    shell script的执行:

    1.直接指令下达:shell.sh档案必须要具备可读与可执行(rx)的权限,然后:

    • 绝对路径:使用/home/dmtsai/shell.sh来下达指令
    • 相对路径:假设工作目录在/home/dmtsai/,则使用./shell.sh来执行
    • 变量[PATH]功能:将shell.sh放在PATH指定的目录内,例如:~/bin/

    2.以bash程序来执行:透过[bash shell.sh]或[sh shell.sh]来执行

     PS:script的执行方式差异(source、sh script、./script)

    • 1.利用直接执行的方式来执行script:比如sh sh02.sh
    • 2.利用source来执行的脚本:在父程序中执行:source sh02.sh 
    //sh01.sh脚本内容如下:
    #!/bin/bash
    #program:
    #       This program shows "Hello World!" in your screen.
    #History:
    #2020/04/27 wendy First release
    echo -e "Hello World!a
    " // -e开启转义
    exit 0
    
    //执行方式一,先赋予权限,在执行
    [wendy@cs011 scripts]$ chmod a+x sh01.sh
    [wendy@cs011 scripts]$ ./sh01.sh
    Hello World!
    
    //执行方式二, /bin/sh 是/bin/bash(连结档),使用sh shell.sh告诉系统,直接bash的功能来执行shell.sh文件内的相关指令。
    [wendy@cs011 scripts]$ sh sh01.sh
    Hello World!
    [wendy@cs011 scripts]$ bash sh01.sh
    Hello World!

    8.2 善用判断式:$?、&&、||

    利用test指令的测试功能

    //检测系统上面某些档案或相关的属性时
    //比如:检查/dmtsai是否存在,同时透过$? 或&& 及||来展现整个结果。
    eg:
    [wendy@cs011 scripts]$ test -e /dmtsai && echo "exits" || echo "not exist"
    not exist
    [root@www scripts]# vi sh05.sh
    #!/bin/bash
    # Program:
    #  User input a filename, program will check the flowing:
    #  1.) exist? 2.) file/directory? 3.) file permissions
    # History:
    PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
    export PATH
    # 1. 输入文件名,并且判断是否真的有输入字符串?
    echo -e "Please input a filename, I will check the filename's type and 
    permission. 
    
    "
    read -p "Input a filename : " filename
    test -z $filename && echo "You MUST input a filename." && exit 0
    # 2. 判断文件是否存在?若不存在则显示信息并结束脚本
    test ! -e $filename && echo "The filename '$filename' DO NOT exist" &&
    exit 0
    # 3. 开始判断文件类型与属性
    test -f $filename && filetype="regulare file"
    test -d $filename && filetype="directory"
    test -r $filename && perm="readable"
    test -w $filename && perm="$perm writable"
    test -x $filename && perm="$perm executable"
    # 4. 开始输出信息!
    echo "The filename: $filename is a $filetype"
    echo "And the permissions are : $perm"

    利用判断符号[],注意事项:

    • 在中括号[]内的每个组件都需要有空格键来分隔。
    • 在中括号内的变数,最好都以双引号括号起来。
    • 在中括号内的常数,最好都以单引号或双引号括号起来。
    //判断$HOME这个变量是否为空
    [ -z "$HOME" ];echo $?
    
    //都有空格键,判断2个值是否相等(逻辑判断)
    [ "$HOME" == "$MAIL" ]  类似于 test $HOME = $MAIL

     shell script的默认变数($0,$1,$2...):

    • $#:代表后接的参数[个数]
    • $@:代表[ "$1" "$2" "$3" "$4" ],每个变量都是独立的(用双引号括起来)
    • $*:代表["$1c$2c$3c$4"],其中c为分隔字符,默认为空格键,所以本例中代表[ "$1" "$2" "$3" "$4" ]之意。

    8.3 shell 的基础操作

    • 对谈式脚本
    • 随日期变化
    • 数值运算

    对谈式脚本:变量内容由用户决定. 

    //read命令用于从标准输入读取数值(单行数据读取)。
     -a:变量[数组],然后给其赋值,默认是以空格为分隔符。
     -d:后面跟一个标识符,其实只有其后的第一个字符有用,作为结束的标志
     -p:后面跟提示信息
     -e:在输入的时候可以使用命令补全功能
     -n:数字
     
    eg:
    //sh02.sh的脚本内容如下
    #!/bin/bash
    #program:
    #       User inputs his first name and last name.Program shows his full name.
    #History:
    #2020/4/27 wendy first release
    PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
    export PATH
    read -p "please input your first name:" firstname
    read -p "please input your last name:" lastname
    echo -e "
     your full name is :$firstname $lastname"
    //执行命令,显示结果
    [wendy@cs011 scripts]$ sh sh02.sh
    please input your first name:wendy //输入wendy
    please input your last name:we  //输入we
    your full name is :wendy we   //显示wendy we

    sh02.sh在子程序中运作:

    随日期变化:利用date进行文件的建立 

    //sh03.sh文件内容
    #!/bin/bash
    #program:
    #       program creates three files,which named by user's input and date command
    #History:
    #2020/4/27 wendy first release
    PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
    export PATH
    echo -e "I will use touch command to create 3 files"
    read -p "please input your filename:" fileuser
    filename=${fileuser:-"filename"}
    date1=$(date --date='2 days ago' +%Y%m%d)# 前两天的日期
    date2=$(date --date='1 days ago' +%Y%m%d)# 前一天的日期
    date3=$(date +%Y%m%d)
    file1=${filename}${date1}
    file2=${filename}${date2}
    file3=${filename}${date3}
    touch "$file1"
    touch "$file2"
    touch "$file3"
    //命令执行结果
    [wendy@cs011 scripts]$ sh sh03.sh
    I will use touch command to create 3 files
    please input your filename:we
    [wendy@cs011 scripts]$ ll
    -rw-rw-r-- 1 wendy wendy 744 Apr 28 12:47 sh03.sh
    -rw-rw-r-- 1 wendy wendy 0 Apr 28 12:47 we20200426
    -rw-rw-r-- 1 wendy wendy 0 Apr 28 12:47 we20200427
    -rw-rw-r-- 1 wendy wendy 0 Apr 28 12:47 we20200428 

    数值运算 :var=$((运算内容)) 或declare -i total=$firstnu*$secnu

    //sh04.sh的内容
    #!/bin/bash
    #program:
    #       user inputs 2 integer numbers;program will cross these two numbers.
    #History:
    #2020/4/27 wendy first release
    PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
    export PATH
    
    echo -e "you should input 2 number,I will cross them!
    "
    read -p "first number:" firstnu
    read -p "second number:" secnu
    total=$(($firstnu*$secnu))
    echo -e "
    The result of $firstnu x $secnu is ==$total"
    
    //执行结果
    [wendy@cs011 scripts]$ sh sh04.sh
    you should input 2 number,I will cross them!
    first number:4
    second number:4
    The result of 4 x 4 is ==16

    8.4 条件判断式

    • 利用if...then:单层简单条件,多重复杂条件,检验$1内容,网络状态,退伍
    • 利用case...esac判断
    • 利用function功能

    单重条件判断式:

    //条件判断式中的内容可以通过 && 或 || 隔开。
    if [ 条件判断式 ];
        then 当条件判断式成立时,可以进行的指令工作内容
    fi
    
    //条件判断式内容
    [ "$yn" == "Y" -o  "$yn" == "y" ] 
    类似于[ "$yn" == "Y" ] || [ "$yn" == "y" ] 
    
    eg:
    if [ "$yn" == "Y" ] || [ "$yn" == "y" ] ;then
        echo "ok,contine"
        exit 0
    fi

    多重、复杂条件判断式:

    //一个条件判断,分成功进行与失败进行(else)
    if [ 条件判断式 ];then
        当条件判断式成立时,可以进行的指令工作内容;
    else
        当条件判断式不成立时,可以进行的指令工作内容
    fi
    
    //多个条件判断(if...elif...elif...else)分多种不同情况执行
    if [ 条件判断式一 ];then
        当条件判断式成立时,可以进行的指令工作内容;
    elif [ 条件判断式二 ];then
        当条件判断式不成立时,可以进行的指令工作内容
    else
        当条件判断式一或二都不成立时,可以进行的指令工作内容
    fi
    
    eg1:
    if [ "$yn" == "y" ] || [ "$yn" == "Y" ];then
        echo "ok,continue"
    else
        echo "no ok!"
    fi
    
    eg2:
    if [ "$yn" == "y" ] || [ "$yn" == "Y" ];then
        echo "ok,continue"
    elif [ "$yn" == "n" ] || [ "$yn" == "N" ];then
        echo "no ok!"
    else
        echo "I don't know!"
    fi     

    case...in...esac判断

    ps:[ case $变量 in ]中[$变量]有两种取得的方式:直接下达式和交互式。

    • 直接下达式:[ script.sh variable ]的方式来直接给予$1这个变量的内容
    • 交互式:透过read这个指令来让用户输入变量的内容
    //case...in...esac判断
    case $变量名称 in 
        "第一个变量内容")
            程序段
        ;;
        "')
        "第二个变量内容")
            程序段
        ;; 
        *)
            程序段
        ;;
    esac
    //需求:使用者能够输入one,two,并且将用户的变量显示在屏幕上
    eg1:sh12.sh内容如下
    #read -p "please your choice:"$choice
    #case $choice in //交互式
    case $1 in //下达式 "one"echo "is one" ;; "two"echo "is two" ;; *) echo "usage $0 {one|two}" ;; esac
    //下达式命令执行:sh sh12.sh two
    //显示结果:is two

    function()功能

    //frame是自定义的执行指令名称,且function一般要放在设定程序的最前面。
    function fname(){
      程序段  
    } 

    8.5 循环(loop)

    • while...do...done,util...do...done(不定循环)
    • for...do...done(固定循环):账号检查,网络状态$(seq)
    • for...do...done的数值处理

    while...do...done,util...do...done(不定循环):

    //while...do...done,中括号内的状态condition就是判断式
    //当condition条件成立时,就进行循环,直到condition的条件不成立才停止
    while [ condition ] 
    do
        程序段落
    done
    
    //until...do...done(不定循环)
    //当condition条件成立时,就终止循环,否则就持续进行循环的程序段
    until[ condition ] 
    do
        程序段落
    done
    //求1+2+...+100的和
    eg1:
    s=0
    i=0
    while [ "$i" != "100" ] 
    do
        i=$(($i+1))
        s=$(($s+$i))
    done
    echo "the result of '1+2+3+...+100'is ==>$s" 

    for...do...done(固定循环):账号检查,网络状态$(seq)

    //for...do...done(固定循环):账号检查,网络状态$(seq)
    for var in con1 con2 con3...
    do
        程序段
    done
    eg1:
    for animal in dog cat elephant
    do
        echo "there are ${animal}s..."
    done

    for...do...done的数值处理

    //初始值:某个变量在循环当中的起始值
    for(( 初始值;限制值;执行步阶 ))
    do
        程序段
    done

    重点:

    shell script 是利用shell的功能所写的一个程序,这个程序是使用纯文本文件,将一些shell的语法与指令(含外部指令)写在里面,搭配正规表示法、管线命令与数据流重导向等功能。

    shell script执行顺序:从上而下、从左而右的分析与执行

    shell script的执行,至少需要有r的权限,若需要直接指令下达,则需要拥有r与x的权限

    script 的执行以source来执行时,代表在父程序的bash内执行之意

    若需要进行判断式,可使用test或中括号[]来处理

    使用sh -x script.sh来进行程序的debug

    9 shell 简单操作

    9.1 变量

    语法:变量名=变量值
    PS:=两边不能有空格
    
    1、使用变量:$变量名
    ex:  Name="wendy"#声明变量
         echo $Name 或 echo ${Name}  #输出变量
    ps:花括号可选
    2、只读变量:readonly 变量
    3、删除变量:unset 变量
    4、字符串变量长度获取:${#字符串变量}
    ps: string="abcd" echo ${#string}  #输出4
    5、字符串变量提取部分:${变量:1:4} #表示从第二个字符开始,截取4个字符
    ex:string="abcdedfg" echo ${变量:1:4} #输出bcde

     在bash中,每一个变量的值都是字符串。

    9.2 变量类型

    局部变量:只对当前shell有效

    环境变量:所有程序都能访问环境变量

    shell变量:可设置

    9.3 符号问题

    单引号:变量无效,任何字符原样输出

    双引号:可使用变量,可以出现转义字符

    ps:拼接字符串用双引号,且变量需要用{}

    注释问题:

    单行注释:#

    多行注释: :<<EOF 注释内容 EOF(EOF可以替换为其他任意字符)

    9.4 数组

    定义数组:数据名=(值1 值2 值3...值n)或数组名=(
    value0
    value1
    value2
    value3
    )或 数据名[0]=value0  数据名[1]=value1
    ex:array_name=(value0 value1 value2)
    读取数组:${数组名[下标]}
    ex:value=${数组名[n]} #@表示获取数组中的单个元素
       length=${#数组名[@ || *]}# @、*表示获取数组所有元素的长度

    9.5 参数处理

    $#  脚本后面接的参数的个数
    $*  脚本后面所有参数,参数当成一个整体输出,每一个变量参数之间以空格隔开
    $@  脚本后面所有参数,参数是独立的,也是全部输出
    $$  脚本运行的当前进程ID号
    $!  后台运行的最后一个进程的ID号
    $?  上一条命令执行后返回的状态,0表示没有错误,0以外其他所有值表示有错误

    9.6 运算符:

    算数运算符: + - * / % = == !=
    关系运算符:-eq -ne -gt -ge -lt -le(= != > >= < <=)
    布尔运算符:! -o -a(or and)
    逻辑运算符: && ||
    字符串运算符:= != -z -n $(= != 判断=0为真 判断!=0为真 判断是空为真)
    文件测试运算符:(-e -r -w -x -s -d -f -c -b)+文件名 文件存在且可读、可写、可执行、至少有一个字符、是目录、普通文件、字符型特殊文件、块特殊文件

    9.7 shell函数:

    [ function ] funname [()]
    {
    action;
    [return int;]
    }
    或者function fun()
    或者fun()
    ps:参数返回,可以显示加;

    9.8 shell 输入/输出重定向:

    command > file 将输出重定向到file
    command < file 将输入重定向到file
    command >> file 将输出以追加的方式重定向到file
    n >& m   将输出文件m和n合并
    n <& m   将输入文件m和n合并
    <<tag    将开始标记tag和结束tag之间的内容作为输入
    /dev/null:不希望在屏幕上显示输出结果 ,重定向到垃圾箱/dev/null
  • 相关阅读:
    GridView动态创建TemplateField的回发问题
    ASP.NET页面生命周期
    php图片叠加
    php文件下载
    mysql 常用操作命令
    转载:图解SQL的Join
    利用iframe来做无刷新上传
    php抽象和接口的区别
    php 循环打开目录读取文件
    mysql存储引擎的对比(一)
  • 原文地址:https://www.cnblogs.com/wendyw/p/11598925.html
Copyright © 2011-2022 走看看