shell基础(上)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了shell基础(上)相关的知识,希望对你有一定的参考价值。

  1. Shell基础(上)

    1.1什么是shell

       Shell是一个命令解释器,它在操作系统的最外层,负责直接与用户对话,把用户的

    输入解释给操作系统.井处理各种各样的操作系统的输出结果,输出屏幕返回给用户

    这种对话方式可以是

    1. 交互的方式:从键盘输入命令,通过/bin/bash的解折,可以立即得到shell的回应

    2. 非交互的方式:脚本

     Shell执行命令分为两种方式

    1. 内置命令:如讲过的cd ,pwd, exitecho等命令.当用户登录系统后,shell以及内置命令就被系统载入到内存,并且一直运行

    2. 一般命令:15,磁盘上的程序文件==>调入内存==>执行命令

     

    1.2什么是shell脚本

    linux命令或语句不在命令行下执行(严格说,命令行也是Shell,而是通过一个程序文件执行时,该程序就被称为Shell脚本或Shell程序

     

      用户可以在Shell脚本中敲入一系列的命令及命令语句组合。这些命令、变量和流程控制语句等有机的结合起来就形成一个功能强大的Shell脚本。

     

    1.2.1 写一个清空/var/log/messages日志的脚本

    1. 日志文件在哪?

    2. 用什么命令可以清空文件

    3. 写一个简单的shell脚本。

    4. 怎样执行脚本?

    5. 进阶:

    有没有考虑到

    1)有没有脚本放在统一的目录

    2)权限:用哪个用户执行文件

    3)清空错文件怎么办,该怎么办

    4)错误提示:有没有成功知不知道

    5)脚本通用性

     

    [[email protected]]# mkdir -p /server/scripts

    [[email protected]]# cd /server/scripts

    [[email protected]]# vim clear_log.sh

    #!/bin/bash

    cd /var/log/

    >messages

    ~

    [[email protected]]# cat clear_log.sh

    #!/bin/bash

    cd /var/log/

    >messages

    [[email protected]]# sh clear_log.sh

    [[email protected]]# cat /var/log/messages  #空的清空了

     

    1.2.2 一个规范的Shell脚本

    [[email protected]~ ]#mkdir -p/server/scripts    #要有规范的存放脚本目录

    [[email protected] ~]# cd/server/scripts/

    [[email protected] cc scripts]# vim clear_log.sh

    #!/bin/bash

    LOG_DIR=/var/log

    ROOT_UID=O   #UID为0时,用户才具有root权限echo $UID

    #要使用root用户执行

    if[ "$UID" -ne "$ROOT _UID" ]

    then

      echo"Must be root to run this script."

      exit 1

      fi

    #||表示前面执行失败则执行后面,区别于&&

    cd $ LOG_DIR 2>/dev/null || {

        echo"Cannot change to necessary directory.”

        exit 1

    }

    cat /dev/null>messages && echo"Logs cleaned up."

    exit 0

    #退出之前返回0表示成功,返回1表示失败。

     

    1.2.3清空日志的三种方法

    echo >test.log

    >test.log

    cat /dev /null >test.log

    #清空内容。保留文件

    1.2.4小结

    Shell就是命令解释器.==>翻译官

    Shell脚本==>命令放在脚本里

     

    1.3Shell脚本在运维工作中的作用地位

    Shell脚本擅长处理纯文本类型的数据,而linux中几乎所有的配置文件、日志文件等都是纯文本类型文件

    第2章 脚本的建立和执行

    2.1Shell脚本的建立

    推荐使用vim编辑器

    2.1.1脚本开头

        规范的Shell脚本第一行会指出由哪个程序(解释器)来执行脚本中的内容。在linux bash编程中一般为,

    #!/bin/bash

    #!/bin/sh<==255个字符以内

    其中开头的“#!”又称为幻数,在执行Shell脚本的时候,内核会根据“#!”后的解释器来确定用0个程序解释脚本中的内容。

    注意:这一行必须在每个脚本顶端的第一行,如果不是第一行则为脚本注释行

     

    2.1.2bash版本

    [[email protected]~]# 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 andredistribute it.

    There is NO WARRANTY, to the extent permitted bylaw.

    2.1.3bash漏洞(破壳漏洞)

    1.4 bash漏洞(破壳漏洞)

    如果是比较老的系统,需要注意shell的版本太低,有漏洞,需要升级shell

    #验证方法

    [[email protected]~]# env x=‘() { :;}; echo be careful‘ bash -c "echo this is a test"

    this is a test

    如果返回2行

    be careful 就是有漏洞需要升级

    #升级方法  yum -y update bash

     

    2.1.4 不同语言脚本的开头写法

    #!/bin/bash

    #!/usr/bin/awk

    #!/bin/sed

    #!/usr/bin/tcl

    #!/usr/bin/per

    #!/usr/bin/env python

        如果脚本开头不指定解释雄,就要用对应的解释器执行脚本。例如bash  test.hpython  test.py

     

    2.1.5 脚本注释

        Shell脚本中,跟在#后面的内容表示注释。注释部分不会被执行,仅给人看。注释可以自成一行,也可以跟在命令后面,与命令同行。要养成写注释的习惯,方便自己与他人。

    最好不用中文注释,因为在不同字符集的系统会出现乱码

     

    2.2脚本的执行

    2.2.1Shell脚本执行的四种方式

    1. 1.     bash script-name sh script-name(推荐使用)

    这种方法是当脚本本身没有可执行权限时常使用的方法

     

     

    1. path/script-name./script-name(全路径或当前路径执行脚本)

    这种方法首先需要给脚本文件可执行权限。

    1. source script-name. script-name注意点号,且点号后有空格。

    2. sh<script-namecat script-name |shcat script-name |bash

    3. 3shell脚本开发的规范和习惯

    4. 开头指定脚本解释器。

    5. 开头加版本版权等信息,可配置~/.vimrc文件自动添加。

    6. 脚本不要用中文注释,尽量用英文注释

    7. 脚本以.sh为扩展名。

    8. 放在统一的目录

    9. 代码书写优秀习惯

    a.       成对的内容一次性写出来,防止遗漏,如[ ]‘ ‘" "

    b.      []两端要有空格,先输入[],退格,输入2个空格,再退格写。

    c.       流程控制语句一次书写完,再添加内容。

    if条件

     then

    内容

    fi

    d.      通过缩进让代码易读。

    e.       脚本中的引号都是英文状态下的引号,其他字符也是英文状态。

    好的习惯可以让我们避免很多不必要的麻烦,提高工作效率

     

    第3章 Shell环境变量

    3.1什么是环境变量

    变量就是用一个固定的字符串(也可能是字符数字等的组合),替代更多史复杂的内这个内容里可能还会包含变量和路径,字符串等其他内容。变量的定义是存在内存容中。

     

    3.2变量类型

    变量分为两类:

    环境变量(也可称为全局变量) :可以在创建他们的Shell及其派生出来的子Shell中使用。环境变量又可以分为自定义环境变量和bash内置的环境变量。

    局部变量(普通变量):只能在创建他们的Shell函数或shell脚本中使用,还记得前而的$user?我们创建的一般都是普通变量。

     

    3.3环境变量

        环搅变量用于定义Shell的运行环境,保证Shell命令的正确执行,Shell通过环境变量来确定登录用户名、命令路径、终端类型、登录目录等,所有的环境变量都是全局变量,可用于所有子进程中,包括编辑器、shell脚本和各类应用。但crond计划任务除外,还需要重新定义环境变量。

        环倍变量可以在命令行中设置,但用户退出时这些变量值也会丢失,因此最好在用户家目录下的bash_profile文件中或全局配$/etc/bashrc, /etc/profile文件或者/etc/profile.d/目录中定义。将环境变量放入profile文件中,每次用户登录时这些变量值都将被初始化。

        通常,所有环境变量都为大写。环境变量应用于用户进程前,都应该用export命令导出。例如-exportOLDBOV=1

    有一些环境变量,比如HOME, PATH, SHELL, UID,USER等,在用户登录之前就已经被/bin/loein程序设置好了。通常环境变量定义并保存在用户家目录下的.bash profile/etc/profile 文件中。

     

    3.3.1查看系统环境变量

    [[email protected] ~]# echo $HOME

    /root

    [[email protected] ~]# echo $PATH

    /usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin

    [[email protected] ~]# echo $SHELL

    /bin/bash

    [[email protected] ~]# echo $UID

    0

    [[email protected] ~]# echo $USER

    root

    [[email protected]~]# env查看系统环境变量

    HOSTNAME=cc

    TERM=xterm

    SHELL=/bin/bash

    HISTSIZE=1000

    SSH_CLIENT=192.168.106.1 49474 22

    SSH_TTY=/dev/pts/0

    USER=root

    LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lz=01;31:*.xz=01;31:*.bz2=01;31:*.tbz=01;31:*.tbz2=01;31:*.bz=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.rar=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36:

    MAIL=/var/spool/mail/root

    PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin

    PWD=/root

    LANG=en_US.UTF-8

    HISTCONTROL=ignoredups

    SHLVL=1

    HOME=/root

    LOGNAME=root

    CVS_RSH=ssh

    SSH_CONNECTION=192.168.106.1 49474 192.168.106.13222

    LESSOPEN=||/usr/bin/lesspipe.sh %s

    G_BROKEN_FILENAMES=1

    _=/bin/env

     

    3.3.2当前终端变量

    [[email protected]~]# echo $PS1

    [\[email protected]\h \W]\$

     

    3.4Shell局部变量

    3.4.1定义局部变量

        局部变量在用户当前的shell生存期的脚本中使用。例如,局部变量OLDBOy取值为ett098,这个值只在用户当前shell生存期中有意义。如果在shell中启动另一个进程或退出,局部变量OLDBOY值将无效。

     

    3.4.1.1 普通字符串定义变量

    变量名=value

    变量=‘value ‘

    变量名="value"

    3.4.1.2  shell中变量名及变量内容的要求

        一般是字母、数字、下划线组成,且以字母开头。如oldboy,oldboy123,

    oldboy_training。变量的内容,可以使用单引号或双引号引起来,或不加引号。

     

    [[email protected] ~]#a=192.168.1.2

    [[email protected] ~]# echo"a=$a"

    a=192.168.1.2

    [[email protected] ~]#b=‘192.168.1.2‘

    [[email protected] ~]#c="192.168.1.2"

    [[email protected] ~]# echo"b=$b"

    b=192.168.1.2

    [[email protected] ~]# echo"c=$c"

    c=192.168.1.2

    3.4.1.3 把一个命令作为变量

    [[email protected] ~]# DATE=`date +%F`

    [[email protected] ~]# echo $DATE

    2017-02-17

    3.4.1.4 小结

    1. CMD=`ls`ls两侧的符号是键盘tab键上面的,不是单引号

    2. 在变量名前加$,可以取得此变量的值,使用echoprintf命令可以显示变量的值,$A${A}写法不同,效果一样,推荐后面的写法

    3. ${WEEK}DAY若变量和其他字符组成新的变量就必须给变量加上大括号{}

    4. 养成将所有字符串变量用双引号括起来使用的习惯,减少编程遇到的怪异错误。"$A""${A}"

    5. 4.2变量名及变量内容定义小结

    6. 变量名只能由字母、数字、下划线组成,且以字母开头。

    7. 规范的变量名写法定义:见名知意

    1)OldboyAge=1 <==每个单词首字母大写

    2)oldboy_age=1<==每个单词之间用“_

    3oldboyAgeSex=1 <==驼峰语法: 首个单词字母小写,其余单词首字母大写

    3.  =号的知识,a=1中的等号是赋值的意思,比较是不是和等为"=="

    4.  打印变量,变量名前接$符号,变量名后紧接字符的时候,要用大括号括起来

    1. 注意变量内容引用方法,一般为双引号,简单连续字符可以不加引号,希望原样输出,使用单引号。

    2. 变里内容是命令要用反引号` `或者$( )把变量括起来使用。

    第4章 Shell特殊变量

    4.1位置变量

    $0 获取当前执行的shell脚本的文件名,如果执行脚本带路径那么就包括脚本路径。

     

    $n 获取当前执行的shell脚本的第n个参数值,n=1..9,当n0时表示脚本的文件名,如果n大于9用大括号括起来{10},参数以空格隔开。

     

    $# 获取当前执行的shell脚本后面接的参数的总个数

     

    4.1.1$0 获取当前执行的shell脚本的文件名,包括路径

    [[email protected] scripts]# vim teshu.sh

    [[email protected] scripts]# cat teshu.sh

    #! /bin/bash

    echo $0

    [[email protected]]# sh teshu.sh

    teshu.sh

    [[email protected]]# sh /server/scripts/teshu.sh

    /server/scripts/teshu.sh

     

    4.1.2$n获取当前执行的shell脚本的第n个参数值

    [[email protected] scripts]# cat teshu.sh

    #! /bin/bash

    echo $0

    echo$1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15   #写法是错误的

     

    [[email protected] scripts]# sh teshu.sh

    teshu.sh

    0 1 2 3 4 5  #显示的是标为红色的部分

    [[email protected] scripts]# cat teshu.sh

    #! /bin/bash

    echo $0

    echo$1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} ${12} ${13} ${14} ${15}    #正确的写法

     

    [[email protected]]# sh teshu.sh  a b c

    teshu.sh

    a b c

     

    4.1.3$#获取当前执行的shell脚本后面接的参数的总个数

    [[email protected] scripts]# cat teshu.sh

    #! /bin/bash

    echo $0

    echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} ${12}${13} ${14} ${15}

    echo $#

    [[email protected]]# sh teshu.sh  {a..z}

    teshu.sh

    a b c d e f g h i j k l m n o

    26

    4.2进程状态变量

    $? 获取执行行上一个指令的返回值(0为成功,非0为失败)

    查找方法man bash,然后搜索 Special Parameters

     

    4.2.1$?

    [[email protected] ~]# cd qqq

    -bash: cd: qqq: No such file or directory

    [[email protected] ~]# echo $?

    127

    [[email protected] ~]# pwd

    /root

    [[email protected] ~]# echo $?

    0

    $?返回值参考

    0表示运行成功

    2权限拒绝

    1~125 表示运行失败,脚本命令、系统命令错误或参数传递错误。

    126找到该命令,但无法执行

    127未找到要运行的命令

    >128命令被系统强制结束

     

     

    生产环境

    1. 用于判断命令、脚本或函数等程序是否执行成功

    2. 若在脚本中调用执行“exit数字”,则会返回这个数字给“$?”变量。

    3. 如果在函数中使用“return数字”,则会以函数返回值的形式传给“$? "

    [[email protected] scripts]# cat teshu.sh

    #! /bin/bash

    echo $0

    echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} ${12}${13} ${14} ${15}

    echo $#

    if[ $1 == 1 ]

      then

        exit 22

    else

        exit 33

    fi

    [[email protected]]# sh teshu.sh  1

    teshu.sh

    1

    1

    [[email protected]]# echo $?

    22

    [[email protected]]# sh teshu.sh  2

    teshu.sh

    2

    1

    [[email protected]]# echo $?

    33

     

    第5章 变量的数值计算

    5.1(())用法(常用于简单的整数运算)

    算术运算符号

    运算符

    意义

    ++   --

    增加及减少,可前置也可放在结尾

    + - ! ~

    一元的正号与负号,非,逻辑与位的取反

    * /  %

    乘法 除法  取余

    + -

    加法 减法

    < <= > >=

    比较符号

    ==   !=

    相等 不相等

    &

    向左位移 向右位移

    ^

    位的AND

    |

    位的异或

    &&

    位的或

    ||

    位的OR

    ?:

    条件表达式

    = +=   -=

    赋值运算符

    **

    幂运算

    [[email protected] scripts]# a=$((2-1))

    [[email protected] scripts]# echo $a

    1

    [[email protected] scripts]# a=$((a++))

    [[email protected] scripts]# echo $a

    1

    [[email protected]]# a=$((a++))

    [[email protected] scripts]# echo $a

    1

    [[email protected]]# a=$((++a))

    [[email protected] scripts]# echo $a

    2

    [[email protected] scripts]# echo $a

    2

    [[email protected]]# a=$((++a))

    [[email protected] scripts]# echo $a

    3

    变量a在前,表达式的值为a,然后a自增或自减,变量a在符号后,表达式值自增或自减,然后a值自增或自减。

    [[email protected] scripts]# cat calculator.sh

    #!/bin/sh

    echo $(($1))

    [[email protected] scripts]# sh calculator.sh 3+2-2*2/1

    1

     

    5.2$[]的用法

    [[email protected] scripts]# echo $[1+1]

    2

    [[email protected] scripts]# echo $[1*3]

    3

     

    第6章 脚本中定义变量

    6.1脚本直接赋值

    [[email protected] scripts]# cat calculator.sh

    #!/bin/sh

    echo $(($1))

    a=6

    b=2

    6.2命令行传参

    利用位置变量

    [[email protected] scripts]# cat calculator.sh

    #!/bin/sh

    echo $(($1))

    a=$6  

    b=$2

     

    第7章 条件测试

    判断某些条件是否成立,成立执行一种命令,不成立执行另外一种命令。

    7.1条件测试语法

    格式:[ 测试表达式 ]

    7.2测试表达式

    方法一

    [[email protected]]# [ -f /etc/hosts ]

    [[email protected] scripts]# echo $?

    0

    [[email protected]]# [ -f /etc/host ]

    [[email protected] scripts]# echo $?

    1

    方法二

    [[email protected]]# [ -f /etc/hosts ]&&echo TRUE||echo FALSE

    TRUE

    [[email protected]]# [ -f /etc/host ]&&echo TRUE||echo FALSE

    FALSE

     

    7.2.1常用的文件测试操作符号

    常用文件测试操作符号

    说明

    -f文件, file

    文件存在且为普通文件则真,即测试表达式成立

    -d文件, directory

    文件存在且为目录文件则真,即测试表达式成立

    -s文件,  size

    文件存在且文件大小不为0则真,即测试表达式成立

    -e文件,  exist

    文件存在则真,即测试表达式成立。只要有文件就行,区别-f

    -r文件,  read

    文件存在且可读则真,即测试表达式成立

    -w文件,write

    文件存在且可写则真,即测试表达式成立

    -x文件,executable

    文件存在且可执行则真,即测试表达式成立

    -L文件,link

    文件存在且为链接文件则真,即测试表达式成立

    f1 -nt f2  newer than

    文件f1f2新则真,即测试表达式成立,根据文件修改时间计算

    f1 -ot f2 older than

    文件f1f2旧则真,即测试表达式成立,根据文件修改时间计算

     

    7.2.2字符串测试操作符

    字符串测试操作符的作用:比较两个字符串是否相同、字符串长度是否为零,字符串是否为NULLBash区分零长度字符串和空字符串。

    常用字符串测试操作符

    说明

    -z "字符串"

    若串长度为0则真,-z理解为zero

    -n "字符串"

    若串长度不为0则真,-n理解为no zero

    "1"  =  "2"

    若串1等于串2则真,可以使用“==”代替“=”

    "1"  !=  "2"

    若串1不等于串2则真,但不能使用==”代替

    特别注意,以上表格中的字符串测试操作符号务必要用""引起来。[ -z  "$string" ]

    字符串比较,比较符号两端最好有空格,参照系统脚本。

    [  "$passwd"    =   "john ]

    [[email protected]]# [ -z " " ]&&echo TRUE||echo FALSE

    FALSE

    [[email protected]]# [ -z "" ]&&echo TRUE||echo FALSE

    TRUE

    [[email protected] scripts]# [ -n "" ]&&echo TRUE||echo FALSE

    FALSE

    [[email protected]]# [ "aa" == "bb" ]&&echo TRUE||echo FALSE

    FALSE

    [[email protected] scripts]# [ "aa" != "bb" ]&&echoTRUE||echo FALSE

    TRUE

     

    7.2.3整数二元比较操作符

    []中使用的比较符

    说明

    -eq

    equal等于

    -ne

    not equal不等于

    -gt

    greater than大于

    -ge

    greater equal大于等于

    -lt

    less than小于

    -le

    less equal小于等于

    [[email protected] scripts]# [ 1 -le 2 ]&&echoTRUE||echo FALSE

    TRUE

    [[email protected] scripts]# [ 1 -ne 2 ]&&echoTRUE||echo FALSE

    TRUE

    [[email protected] scripts]# [ 1 -eq 2 ]&&echoTRUE||echo FALSE

    FALSE

    [[email protected] scripts]# [ 1 -lt 2 ]&&echoTRUE||echo FALSE

    TRUE

    [[email protected] scripts]# [ 1 -gt 2 ]&&echoTRUE||echo FALSE

    FALSE

    7.2.4逻辑操作符

    []中使用的逻辑操作符

    说明

    -a

    and,两端都为真则真

    -o

    or,有一个真则真

    not,相反则真

    [[email protected] scripts]# [ "1" !="2" -a 1 -eq 2 ]&&echo TRUE||echo FALSE

    FALSE

    [[email protected] scripts]# [ "1" !="2" -o 1 -eq 2 ]&&echo TRUE||echo FALSE

    TRUE

     

    7.2.5小结

    1. 多个[]之间的逻辑操作符是&&||

    2. 2.     &&前面成功执行后面

    3. 3.     || 前面不成功执行后面


    本文出自 “11714322” 博客,谢绝转载!

    以上是关于shell基础(上)的主要内容,如果未能解决你的问题,请参考以下文章

    Shell编程基础篇-上

    Shell编程基础篇-上

    Shell基础知识(上)

    Linux5.2 Shell基础上

    《shell编程实战》第3章shell变量基础(上)

    linux12shell编程 --> shell基础02