zoukankan      html  css  js  c++  java
  • shell基础

    ============================================================================
    shell脚本基础
    ============================================================================
    一、Shell特性回顾
    内壳
    1、命令历史、命令补全
    1000条命令历史
    命令历史的使用技巧:
    !n:执行第n条历史命令
    !-n:执行倒数第n条历史命令
    !!:上一条命令
    !string:最近和string匹配历史命令
    !$:上一条命令的最后一个参数
    Esc,. 先按esc,然后按.
    Alt+. 同时按住alt和.
    补全:tab
    命令补全
    路径补全
    2、管道,重定向
    | < > << >>

    3、命令别名
    alias
    4、命令行编辑
    5、命令行展开
    6、文件名通配 globbing
    *:匹配任意字符,0个或多个
    ?:匹配任意单个字符
    []:匹配指定范围内的任意单个字符
    [abc],[a-m],[a-z],[0-9],[a-zA-Z]
    [[:space:]] 空白字符
    [[:punct:]] 标点符号
    [[:lower:]] 小写字母
    [[:upper:]] 大写字母
    [[:alpha:]] 大小写字母
    [[:digit:]] 数字 [0-9]
    [[:alnum:]] 数字和大小写字母
    可以使用 man 7 glob获取帮助
    [^]:匹配指定范围外的任意单个字符 [^0-9]

    1、创建a123, cd6, c78m, c1 my, m.z, k 67, 8yu, 789等文件;
    注意,以上文件是以逗号隔开的,其它符号都是文件名的组成部分
    2、显示所有以a或m开头的文件
    ls [am]*

    3、显示所有文件名中包含了数字的文件;
    ls *[0-9]*
    ls *[[:digit:]]*

    4、显示所有以小写字母开头后面跟两个字符的文件:
    ls [a-z]??
    ls [[:lower:]]??

    5、显示文件名开头中包含了非字母(大小写字母)文件;
    ls [^a-zA-Z]*
    ls [^[:alpha:]]*

    7、变量
    8、编程

    用户登录shell类型:
    bash的配置文件:
    全局配置:
    /etc/profile,/etc/profile.d/*.sh,/etc/bashrc
    个人配置:
    ~/.bash_profile,~/.bashrc

    profile类的文件:
    设定环境变量
    运行命令或脚本

    bashrc类的文件:
    设定本地变量
    定义命令别名

    登录式shell如何读取配置文件?
    /etc/profile-->/etc/profile.d/*.sh-->~/.bash_profile-->~/.bashrc-->/etc/bashrc

    非登录式shell如何读取配置文件?
    ~./.bashrc-->/etc/bashrc-->/etc/profile.d/*.sh

    登出的时候影响的文件:
    ~/.bash_history 用户级 退出bash时执行
    ~/.bash_logout 用户级 退出bash时执行
    影响bash shell的其它文件
    bash登录和欢迎信息
    /etc/issue 登录前显示的信息(本地登录)
    /etc/issue.net 登录前显示的信息(网络登录)
    /etc/motd 登录后显示的信息


    Shell编程特点
    shell脚本:命令的堆砌,按实际需要,结合命令流程控制机制实现的源程序
    Shell脚本规范
    1、 开头指定脚本解释器
    #!/bin/sh或#!/bin/bash
    其他行#表示注释
    名称见名知义 backup_mysql.sh,以sh结尾
    2、 开头加版本版权等信息
    #Date:创建日期
    #Author:作者
    #Mail:联系方式
    #Function:功能
    #Version:版本
    3、 脚本中尽量不用中文注释
    别吝啬添加注释,必要的注释方便自己别人理解脚本逻辑和功能;
    尽量用英文注释,防止本机或切换系统环境后中文乱码的困扰;
    单行注释,可以放在代码行的尾部或代码行的上部;
    多行注释,用于注解复杂的功能说明,可以放在程序体中,也可以放在代码块的开始部分
    代码修改时,对修改的内容
    5、 多使用内部命令
    内部命令可以在性能方面为你节省很多。
    6、 没有必要使用cat命令
    eg:cat /etc/passwd | grep guru
    使用以下方式即可
    eg:grep guru etc/passwd
    7、 仔细阅读出错信息
    有时候我们修改了某个错误并再次运行后,系统依旧会报错。然后我们再次修改,但系统再次报错。这可能会持续很长时间。但实际上,旧的错误可能已经被纠正,只是由于出现了其它一些新错误才导致系统再次报错
    8、 脚本以.sh为扩展名
    eg:script-name.sh

    Shell脚本运行
    方法一:切换到shell脚本所在的目录(此时,称为工作目录)执行shell脚本
    方法二:以绝对路径的方式去执行bash shell脚本:
    方法三:直接使用bash 或sh 来执行bash shell脚本:
    方法四:在当前的shell环境中执行bash shell脚本:source或.
    区别:
    1、方法三:可以在脚本中不指定解释器,脚本可以没有执行权限
    2、方法一和方法二脚本需要有执行权限,./script_name.sh 或/path/script_name.sh
    3、方法四:当前shell执行,方法1-3开启子shell

    -----------------------------------------------------------------------------------------------
    变量
    -----------------------------------------------------------------------------------------------

    1、变量基础

    命名
    变量名称:
    1、只能包含字母、数字和下划线,并且不能数字开头;
    2、不应该跟系统中已有的环境变量重名;
    3、最好做到见名知义;
    变量名=变量值
    变量值=前面不能有空格,变量值本身有空格等要用引号
    file_path
    FilePath
    echo $var_name
    shell:弱类型编程语言
    强:变量在使用前,必须事先声明,甚至还需初始化;
    弱:变量用时声明,甚至不区分类型;
    declare -i 定义整形变量
    设定
    查看 set env
    取消与清空变量:
    unset VAR_NAME
    若不加任何选项,首先尝试取消变量,若失败,再试着取消与该变量同名的函数。
    unset -v VAR_NAME #取消变量
    unset -f FUNCTION_NAME #取消函数

    清空变量方法:
    VAR_NAME=

    引号:
    '':单引号,所见及所得
    "":引号内变量替换
    ``:反撇号。引用命令 $()

    2、变量分类
    环境变量
    HOME:家目录位置
    LANG:系统语言变量
    PATH:命令搜索路径
    PS1:提示符
    HOSTNAME:主机名称
    SHELL:当前用户shell类型
    MAIL:当前用户的邮件存放目录
    RANDOM:随机数变量

    示例:设置java环境变量
    #配置环境变量/etc/profile
    export JAVA_HOME=/usr/java/jdk1.6.0_45
    export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
    export PATH=$PATH:$JAVA_HOME/bin
    #使配置生效 #source /etc/profile
    #检测: # java –version
    java version "1.6.0_45"
    Java(TM) SE Runtime Environment (build 1.6.0_45-b06)
    Java HotSpot(TM) 64-Bit Server VM (build 20.45-b01, mixed mode

    #也可以脚本形式(比如java.sh)定义在/etc/profile.d/下面

    输出成全局变量使用 export
    方法1:先定义,在输出
    JAVA_HOME=/usr/java/jdk1.6.0_45
    export JAVA_HOME

    方法2:export JAVA_HOME=/usr/java/jdk1.6.0_45
    生产环境定义oracle用户环境变量
    [oracle@oracle11G ~]$ cat .bash_profile
    # .bash_profile

    # Get the aliases and functions
    if [ -f ~/.bashrc ]; then
    . ~/.bashrc
    fi

    # User specific environment and startup programs

    PATH=$PATH:$HOME/bin

    export PATH
    umask 022
    export ORACLE_BASE=/u01/app/oracle
    export ORACLE_SID=orcl
    export ORACLE_HOME="$ORACLE_BASE/product/11.2.0.1.0/dbhome_1"
    export PATH="$ORACLE_HOME/bin:$PATH"
    export NLS_LANG=AMERICAN_AMERICA.ZHS16GBK


    特殊变量
    $# :参数个数
    $* :参数列表
    $? :返回上一条命令执行结果,0和非0
    $$ :
    $@ :参数列表
    $n :位置参数 $1 $2
    $0 :脚本名称
    预定义变量:$$、$*、$@、$#、$?
    示例:
    脱义
    # cat var2.sh
    #!/bin/sh

    echo "script name($0): $0"
    echo "all parameters numbers($#): $#"
    echo "all parameters($*): $*"
    echo "all parameters($@): $@"
    echo "PID of the script($$): $$"
    echo "success of the previous command($?): $?"

    $* 与$@ 区别:仅仅在加双引号时区别
    $* 获取当前shell的所有参数,将所有命令行参数视为单个字符串,相当于”$1$2$3”
    $@ 将所有参数以”$1” “$2” “$3”形式,每个参数作为个体


    # set -- "I am" test command
    [root@localhost Scripts]# for i in "$*";do echo $i;done
    I am test command
    [root@localhost Scripts]# for i in "$@";do echo $i;done
    I am
    test
    command
    [root@localhost Scripts]# for i;do echo $i;done
    I am
    test
    command

    只读变量
    将变量配置成为 readonly 类型,该变量不可被更改内容,也不能 unset
    定义方法:
    方法一:
    readonly [-fap] [变量定义]
    -f 定义只读函数
    -a 定义只读数组变量
    -p 显示系统中全部的变量列表
    方法二:
    declare –r 变量定义

    readonly

    read -p
    read命令行中也可以不指定变量.如果不指定变量,那么read命令会将接收到的数据放置在环境变量REPLY中。

    3.变量运算

    算术扩展 $((算术式)) r=$((2+5*8))
    外部程序expr expr 算术式 r=`expr 4 + 2`
    $[] $[算术式] r=$[1+2]
    内置命令declare declare –i 变量=算术式 declare –i r=2+3
    内置命令let let算术式 let r=3+4
    bc

    expr:运算符左右必须要有空格

    + 加法 `expr $a + $b` 结果为 30。
    - 减法 `expr $a - $b` 结果为 10。
    * 乘法 `expr $a * $b` 结果为 200。
    / 除法 `expr $b / $a` 结果为 2。
    % 取余 `expr $b % $a` 结果为 0。
    = 赋值 a=$b 将把变量 b 的值赋给 a。
    == 相等则返回 true [ $a == $b ] 返回 false。
    != 不相等则返回 true [ $a != $b ] 返回 true。

    示例:编写一个 Shell 程序,从键盘读入两个整数,然后做加减乘除,并输出结果。

    4.变量扩展
    取字符串
    规则1:${变量名:位置起点}
    含义:由指定的位置起点开始,截取子字符串到字符串结束,起点由0开始

    规则2:${变量名:位置起点:长度}
    含义:由指定的位置起点开始,截取指定长度的字符串,起点由0开始


    计算子串长度
    规则:${#变量名称}
    含义:表示返回变量名称的字符串长度

    对比样式:
    ${变量#关键词} 最短匹配,从左到右
    ${变量##关键词} 最长匹配,从左到右

    ${变量%关键词}
    ${变量%%关键词}

    变量替换:
    ${var:-word}:表示如果 var 已经被赋值,则取它的值,否则取word 的值,但var不改变。
    ${var:=word}:表示如果 var 已经被赋值,则取它的值,否则取word 的值,同时将 word 赋给 var 。
    ${var:+word}:表示如果 var 已经被赋值,则取它的值,否则var 变量置为空。
    ${变量/旧字符串/新字符串}
    ${变量//旧字符串/新字符串}

    截取:
    由字符串前面开始对比删除最短的相符者
    语法:${待测变量#样式}
    说明:从待测变量的值的左边开始对比,删除最短符合样式的字符串

    ${待测变量##样式}

    ${待测变量%样式}

    ${待测变量%%样式}


    -----------------------------------------------------------------------
    条件测试
    -----------------------------------------------------------------------
    条件判定的依据:判定一条命令是否执行成功 $?
    判断方法:命令执行的返回码, 0:TRUE( 成功 ) ,非 0:FALSE( 失败 )
    条件测试的语法:
    格式1:[ expression ]
    格式2:test expression
    格式3:[[ expression ]]
    格式1与格式2等效

    1、整数测试
    -eq 等于
    -ne 不等
    -gt 大于
    -lt 小于
    -ge 大于等于
    -le 小于等于

    2、文件测试
    -e FILE:存在
    -f FILE:文件
    -d PATH:目录
    -r FILE:只读权限
    -w FILE:写权限
    -x FILE:执行权限

    3、字符串比较
    ==
    !=
    -n string:
    -z string:

    示例:
    从键盘输入两个字符串,判断这两个字符串是否相等,如相等输出。
    比较字符串长度是否大于零

    4、逻辑操作符
    [ ]中使用 [[ ]]中使用 说明
    -a && 与,两端都为真,则真
    -o || 或,两端有一个为真则为真
    ! ! 非,相反则为真
    示例:分别给两个字符变量赋值,一个变量赋予一定的值,另一个变量为空,求两者的与、或操作
    5、命令执行顺序
    ; --命令的顺序执行# date ; ls -l /etc/passwd
    && --前面命令执行不成功,后面的命令不执行# mkdir /mnt/iso && mount /dev/sr0 /mnt/iso
    || --如果前面命令成功,后面就不执行,如果前面不成功后面就执行

    命令1 && 命令2
    1、命令1执行结果为假,命令2不会执行
    2、命令1执行结果为真,接着执行命令2
    命令1 || 命令2
    1、命令1执行结果为真,命令2不会执行
    2、命令1执行结果为假,接着执行命令2
    示例:
    如果用户user6不存在,就添加用户user6;
    如果用户存在,就显示用户已存在;否则,就添加此用户;
    如果用户不存在,就添加;否则,显示其已存在;
    如果目录/abc存在给出提示信息目录已存在,否则创建目录

  • 相关阅读:
    NPM采用Rust以消除性能瓶颈
    Nest.js 6.0.0 正式版发布,基于 TypeScript 的 Node.js 框架
    Nest.js 6.0.0 正式版发布,基于 TypeScript 的 Node.js 框架
    【大数据分析】学习之路详解
    【大数据分析】学习之路详解
    Vue Router路由守卫妙用:异步获取数据成功后再进行路由跳转并传递数据,失败则不进行跳转
    RabbitMQ简述
    CAShapeLayer
    IOS杂记
    AfterEffects 关键帧辅助功能
  • 原文地址:https://www.cnblogs.com/sxchengchen/p/7748431.html
Copyright © 2011-2022 走看看