zoukankan      html  css  js  c++  java
  • shell脚本基础、变量

    shell脚本基础
    知识要点
    掌握Shell脚本的基础知识
    学会使用Shell变量
    学会编写简单的Shell脚本
    Shell脚本的应用环境
    学习shell脚本的基本流程
    看、想、
    shell脚本用在什么地方
    编写常用系统维护工具菜单
    重要的性能参数、进程和日志分析
    自动实现数据备份计划
    自动批量搭建特定系统环境
    防火墙自动配置脚本
    服务器的配置文件安全比对
    对批量设备进行远程巡检
    Shell脚本的组成元素
    shell脚本的基本组成
    • 声明和注释*
    • 系统命令
    • 文本处理工具(grep、cut、sed、awk…)
    • 各种变量
    • 各种条件判断
    • 循环结构语句
    • 各种函数
    Shell的作用
    Shell的作用 —— 命令解释器,“翻译官”
    介于系统内核与用户之间,负责解释命令行
    Shell的种类和切换
    登录Shell
    • 指用户每次登录系统后自动加载的Shell程序,大多数Linux系统采用 /bin/bash 作为默认登录Shell
    • /etc/shells 文件记录了系统支持的有效登录Shell
    如何切换Shell环境
    • 临时切换:直接执行其他Shell程序,例如ksh、zsh等
    • 返回到原来的Shell环境时可以执行“exit”命令或者按Ctrl+D快捷键
    • 更改用户登录Shell:
    • 需修改 /etc/passwd 文件中用户记录的最后一个字段
    • 或执行:usermod -s Shell程序路径 用户名
    [root@localhost ~]# cat /etc/shells    //查看有哪些shell
    /bin/sh
    /bin/bash
    /sbin/nologin
    /bin/tcsh
    /bin/csh
    /bin/ksh
    Shell初始化
    bash初始化
    • 登录shell
    指的是输入用户名、密码, 从系统登录时执行的第一个程序(自动启动)
    • 非登录shell(手工启动)
    登录系统后, 在login shell里启动的shell是非login shell
    如执行bash命令、在图形中打开终端均是开一个非登录shell
    bash启动时,会进行初始化,初始化就是执行一些脚本,有哪些脚本呢?
    分2种情况:
    • 第1种登录时启动的bash,登录shell
    初始化脚本执行顺序:/etc/profile->/etc/profile.d/*.sh->~/.bash_profile->~/.bashrc->/etc/bashrc
    如果这些脚本中的变量发出冲突,那么以最后一个脚本的设置生效
    • 第2种登录后,启动的bash,非登录shell
    初始化脚本执行顺序:~/.bashrc->/etc/bashrc->/etc/profile.d/*.sh
    初始化主要是定义一些变量、别名和函数
    Shell启动配置文件的区别
    (环境变量)
    /etc/profile:配置全局环境变量,影响所有用户
    ~/.bash_profile :配置个人环境,影响一个用户
    (函数,别名)
    /etc/bashrc :配置全局的别名或者shell选项,影响所有用户
    ~/.bashrc :配置个人别名或者shell选项,影响一个用户
    登录和非登录Shell区别
    登录Shell负责系统全局环境(env)初始化,会读取所有启动配置文件
    非登录Shell默认会继承登录shell的环境变量,为了加快速度,无需读取所有启动配置文件,只需读取少量局部配置文件
    退出登录Shell:~/.bash_logout
    Bash的命令历史
    命令历史
    保存用户曾经执行过的命令操作
    存放位置:~/.bash_history 文件
    查看历史命令
    使用↑、↓按键逐条翻看,允许编辑并重复执行
    执行:history
    清除历史命令
    执行:history -c
    [root@localhost root]# history
    ……
    556  useradd  jerry
    557  passwd  jerry
    558  crontab  -e  -u  jerry
    559  crontab  -l  -u  jerry
    调用历史命令
    !n:执行历史记录中的第n条命令
    !str:执行历史记录中以“str”开头的命令
    设置记录历史命令的条数
    修改 HISTSIZE 参数(默认为1000条)
    [root@localhost root]# !562
    crontab -l -u jerry
    no crontab for jerry
    [root@localhost ~]# vi /etc/profile
    HISTSIZE=200
    Bash的命令别名
    命令别名
    为使用频率较高的复杂命令行设置简短的调用名称
    存放位置:~/.bashrc
    查看命令别名
    格式:alias [别名]
    设置命令别名
    执行:alias 别名='实际执行的命令'
    取消已设置的命令别名
    格式:unalias 别名
    unalias -a
    [root@localhost ~]# alias
    alias cp='cp -i'
    alias l.='ls -d .* --color=tty'
    alias ll='ls -l --color=tty'
    alias ls='ls --color=tty'
    alias mv='mv -i'
    alias rm='rm -i'
    ……
    编写第一个Shell脚本
    编写脚本代码
    从上往下,按行执行,错误跳过,继续执行
    • 使用vi文本编辑器
    • 每行一条Linux命令,按执行顺序依次编写
    #!/bin/bash

    #这是我的第一个脚本:打印Hello world
    #脚本版本
    #作者
    #日期

    str="hello world"

    echo ${str}
    ////手工执行
    [root@localhost ~]# cd /opt/scripts
    [root@localhost scripts]# bash first_script.sh 
    hello world
    赋予可执行权限
    • 使脚本具有可执行属性
    [root@localhost ~]# chmod +x first_script.sh
    [root@localhost ~]# ls -l first_script.sh
    -rwxr-xr-x 1 root root 144 04-26 15:02 first_script.sh
    [root@localhost scripts]# ./first_script.sh 
    hello world
    [root@localhost scripts]# /opt/scripts/first_script.sh 
    hello world
    执行脚本文件
    • 方法一:脚本文件路径(要求脚本有x权限)
    • 方法二:bash 脚本文件路径(要求脚本有x权限)
    • 方法三:source 或者. 脚本文件路径(不要求脚本有x权限)
    [root@localhost ~]# ./first.sh     // 必须有 x 权限
    /boot
    -rw-r--r-- 1 root root 1.8M 2010-03-17 vmlinuz-2.6.18-194.el5
    [root@localhost ~]# bash /first.sh     // 必须有 x 权限
    /boot
    -rw-r--r-- 1 root root 1.8M 2010-03-17 vmlinuz-2.6.18-194.el5
    [root@localhost ~]# source /first.sh     //不要求 x 权限
    /boot
    -rw-r--r-- 1 root root 1.8M 2010-03-17 vmlinuz-2.6.18-194.el5
    执行脚本方法的区别
    • 区别1:
    方法一、二:要求脚本有x权限
    方法三:不要求脚本有x权限
    • 区别2:
    方法一、二:会产生新的bash进程,有新的bash进程来解析脚本中的代码
    方法三:不会产生新的bash进程,会使用当前的bash进程来解析脚本中的代码
    脚本结构
    1. 声明解释器(声明)
    #!/bin/bash
    1. 注释信息
    #这是我的第一个脚本:打印Hello world
    #脚本版本
    #作者
    #日期
    1. 定义变量、函数
    2. 实现功能
    [root@localhost ~] vi /first.sh
    #!/bin/bash
    # This is my first Shell-Script.
    cd /boot
    echo "当前的目录位于:"
    pwd
    echo "其中以vml开头的文件包括:"
    ls -lh vml*
    练习:
    写脚本:
    实现修改root用户的密码
    要求:
    修改密钱,提示“准备修改root的密码”
    修改密码,不要有任何的输出
    修改后,提示“修改root的密码完成”
    Shell变量的作用、类型
    变量的作用
    • 为灵活管理Linux系统提供特定参数,有两层意思:
    • 变量名:使用固定的名称,由系统预设或用户定义
    • 变量值:能够根据用户设置、系统环境的变化而变化
    变量的类型
    • 自定义变量:由用户自己定义、修改和使用
    • 环境变量:由系统维护,用于设置工作环境
    • 位置变量:通过命令行给脚本程序传递参数
    • 预定义变量:Bash中内置的一类变量,不能直接修改
    按变量使用的范围
    • 局部变量:只在当前的shell中有效
    • 全局变量:子shell会从父shell继承的变量
    自定义变量
    定义新的变量
    • 变量名要求以英文字母或下划线开头,不能以数字开头,区分大小写,约定俗成为大写,但不强制
    • 等号两边不要空格
    • 格式:变量名=变量值(有空格: “asdsadsad a”,空格是命令行的分隔符)
    查看变量的值
    • 格式:echo $变量名
    [root@localhost ~]# DAY=Sunday 
    [root@localhost ~]# echo $DAY     //通过$符号引用指定名称的变量值
    Sunday 
    [root@localhost ~]# DAY=“Today is Sunday”//变量值有空格用双引号括起来
    [root@localhost ~]# echo $DAY
    Today is Sunday
    引用变量:
    如果变量名容易和后边的字目和下划线连在一起导致混淆,则应该使用大括号将变量名括起来
    ${变量名} 
    //
    [root@localhost ~]# DAY=Sunday
    [root@localhost ~]# echo “Today is Sunday ” > $DAY_file.txt
    [root@localhost ~]# ls -a
    . .. .txt
    [root@localhost ~]# echo “Today is Sunday ” > ${DAY}_file.txt
    [root@localhost ~]# ls -a
    . .. Sunday_file.txt
    可以将命令的执行结果直接赋值给变量
    var2=$( rpm -qf $(which fdisk) ) 
    readonly可将变量设置为只读,变量一旦设置为只读,任何用户不能对此变量进行重新赋值
    • variable=value #先对一个变量进行赋值
    • readonly variable #将variable设为只读
    利用unset命令可以清除变量的值
    • 格式:unset 变量名
    shell命令行替换
    bash shell 在解释命令前替换某些命令行元字符
    • 统配符替换:*、?、[a-z]
    • 历史命令替换:!!、!n、!str
    • 代字号替换:~、~用户名
    • 变量替换:$变量名、${变量名}
    • 大括号替换:{a,b,c}file、{aa,bb}/{aa,bb}
    • 算术替换:+、-、*、/
    shell中引号
    引用和转义字符
    • 使用特殊字符时,就是表示本身,不使用其特殊意义
    •  :避免下一个字符被shell解释
    • \:表示
    • 双引号 “ ”:避免双引号内除了$、!和`(反引号)以外的其它字符被shell解释
    (没有内外层,就近)
    • 单引号 ‘ ’:避免单引号内的任何字符被shell解释(没有内外层,就近)
    • 反引号 ``:命令替换,提取命令执行后的输出结果(没有内外层,就近)
    • 单引号、双引号、反引号的区别
    shell替换发生在命令运行之前
    echo命令
    在屏幕显示字符串
    echo命令的-e选项表示将转义符后跟字符形成的特殊字符解释成特殊意义
    符号
    意义
    新的一行
    表示Tab
    [root@localhost scripts]# echo -e "123
    123"
    123
    123
    [root@localhost scripts]# echo - "123
    123"
    - 123n123
    自定义变量
    read命令从键盘输入内容为变量赋值
    • 格式: read [选项] 变量名
    • -p:提示信息
    • -s:隐藏输入
    • -t:指定超时时间
    • -n:指定读取的长度
    #!/bin/bash
    read  -p  "please input you name: " name
    read -n3 -p "input password: " pass
    echo -e "
     your username is $name password is $pass"
    设置变量的作用范围export
    • 格式1:export 变量名 ...
    • 格式2: export 变量名=变量值 ...
    • —— 两种格式可以混合使用
    • export 查看全局变量
    [root@localhost ~]# echo $FILESVR
    filesvr.sxjy.com
    [root@localhost ~]# export FILESVR    //导出为全局变量
    [root@localhost ~]# bash      
    [root@localhost]~# echo $FILESVR       //子程序引用全局变量
    filesvr.sxjy.com
    全局变量
    查看全局变量
    • set命令可以查看所有的Shell变量,其中包括全局变量
    • env命令只查看全局变量
    [root@localhost root]# set
    ……
    SHELL=/bin/bash
    TERM=xterm
    UID=0
    USER=root
    consoletype=pty
    环境变量
    环境变量
    • 由系统提前创建,用来设置用户的工作环境
    • 配置文件: /etc/profile、~/.bash_profile
    常见的环境变量:
    • PWD、PATH
    • USER 、LOGNAME、UID、PPID、SHELL、HOME
    • PS1、$PS2
    [root@localhost ~]# echo $PATH
    /usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
    [root@localhost ~]# PATH="$PATH:/root"
    [root@localhost ~]# echo $PATH
    /usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin:/root
    间接引用变量
    二次引用(间接取值)
    [root@yuelu0324 tmp]# a=b
    [root@yuelu0324 tmp]# b=1
    [root@yuelu0324 tmp]# echo ${${a}}
    -bash: ${${a}}: bad substitution
    [root@yuelu0324 tmp]# echo ${$a}
    -bash: ${$a}: bad substitution
    [root@yuelu0324 tmp]# echo ${!a}
    1
    ${}
    位置变量
    位置变量
    • 表示为 $n,n为1~9之间的数字
    • 大于9的位置参数要用{},例如${10},$0表示叫脚本本身
    预定义变量
    预定义变量
    • $#:命令行中位置变量的个数
    • $*:所有位置变量的内容(较少使用)
    • $@:所有位置变量的内容
    • $0:当前执行的进程/程序名
    • $$ :当前shell的PID值, echo $$; ps $$, 常用作临时变量的后缀
    • $?:上一条命令执行后返回的状态,当返回状态值为0时表示执行正常,非0值表示执行异常或出错
    • $RANDOM :随机数,可以作为临时文件名
    touch abc$RANDOM.txt
    位置变量示例
    对比$*和$@的区别
    返回值判断
    有条件运行多个命令
    • cmd1 && cmd2
      • cmd1成功了(返回值为0)才会运行cmd2
    • cmd1 || cmd2
      • cmd1失败了(返回值为非0)才会运行cmd2
    [root@localhost ~]# rpm -q bind &>/dev/null  && echo ok || echo no
    no
    [root@localhost  ~]# rpm -q setup &>/dev/null  && echo ok || echo no    
    ok
    备份脚本使用位置变量和预定义变量
    [root@localhost ~]# cat bak.sh
    #!/bin/bash
    TARFILE=bak-`date +%s`.tgz  //Unix的时间戳,从1970-1-1 0:0:0 到某个时间的秒数
    tar zcf $TARFILE $@ &> /dev/null
    echo "已执行 $0 脚本,"
    echo “共完成 $# 个对象的备份"
    echo “具体包括: $*
    [root@localhost ~]# ./bak.sh  /etc/passwd  /etc/shadow 
    已执行 ./bak.sh 脚本,
    共完成 2 个对象的备份
    具体包括:/etc/passwd /etc/shadow
    Bash的重定向操作
    改变标准输入、标准输出、标准错误的方向
    类型
    操作符
    用途
    重定向标准输入
    <
    将命令中接收输入的途径由默认的键盘更改为指定的文件
    重定向标准输出
    >
    将命令的执行结果输出到指定的文件中,而不是直接显示在屏幕上
    >>
    将命令执行的结果追加输出到指定文件
    重定向标准错误
    2>
    清空指定文件的内容,并将标准错误信息保存到该文件中
    2>>
    将标准错误信息追加输出到指定的文件中
    重定向标准输出和 标准错误
    &>
    将标准输出、标准错误的内容全部保存到指定的文件中,而不是直接显示在屏幕上
    &>>
    Bash4.0以上才支持,rhel5不支持
    Here Document
    <<
    命令序列传递到一个交互程序或者命令中
    Here Documet用法
    传递命令序列到程序
    [root@localhost ~]# lftp 10.10.10.1 << EOF
    > ls pub
    > get pub/passwd  
    > quit      
    > EOF //后面一定不要有空格
    -rw-r--r-- 1 0 0 1759 Jul 11 06:00 passwd
    [root@localhost ~]# cat << EOF > test.sh
    > #!/bin/bash
    > echo "this is here document test"
    > EOF
    [root@localhost ~]# cat test.sh
    #!/bin/bash
    echo "this is here document test"
    Here Documet示例
    编写脚本自动创建mysql数据库,创建完毕显示结果
    #!/bin/bash
    read -p "请输入要创建数据库的名称:" name
    mysql -u root -p123 << EOF
    create database $name;
    show databases;
    EOF
    [root@localhost test]# bash test.sh
    请输入要创建数据库的名称:sxjy
    Database
    information_schema
    cacti
    mysql
    sxjy
    案例分析
    实验案例1
    编写脚本显示如下图所示效果,分析显示的结果
    name="hello"
    myname0='My name is $name'
    myname1="My name is '$name'"
    myname2='My name is "$name"' 
    myname3="My $name is "$name""
    myname4='My $name is '$name''
    echo $myname0
    echo $myname1
    echo $myname2
    echo $myname3
    echo $myname4
    实验案例2
    编写脚本显示如下图所示效果,要求选择一个菜单后,不用按回车马上显示出结果
     ***系统管理工具***

     1.      显示磁盘空间信息
     2.      显示网络接口信息
     3.      显示内存使用信息
     0.      退出菜单

                    输入选项: 3
    你的选择是 3

    实验案例3
    编写脚本,根据输入的用户名和密码(密码不能显示出来)自动新建用户并配置密码,脚本运行如下图所示(不能显示多余的提示)
    add new user: txy
    user txy password: 
    user txy is ok
    实验案例4
    编写脚本实现下列功能
    • 脚本的功能是统计某个文件夹下有多少个文件夹,包括子文件夹和隐藏文件夹,注意不要把查找目录本身.和..算进来
    • 脚本需要接一个参数就是文件夹的绝对路径位置
    • 运行完毕显示“The number of directory: 数目”
    [root@localhost ~]# ./counter.sh /usr
    The number of directory: 7511
    [root@localhost ~]# ./counter.sh /etc
    The number of directory: 257
    [root@localhost ~]# ./counter.sh /root
    The number of directory: 169
    实验案例6
    编写脚本实现下列功能
    • 脚本的功能是统计某个文件夹下,某种文件后缀名的文件的数目
    • 脚本的参数就是接需要查找的文件的后缀名,可以有多个参数
    • 目录路径和文件名的后缀,通过位置参数传入
    [root@localhost test1]# ./test.sh /etc conf  log
    以conf结尾的文件的数目是: 311
    以log结尾的文件的数目是: 6
    实验案例7
    • 利用Here Document创建本地YUM源配置文件
    • 通过参数指定光盘挂载点
    • 挂载点如果不存在需要创建
    • 备份/etc/yum.repos.d/目录下的其它配置文件
    • 最后显示yum is ok,不能显示多余的正确或错误提示
  • 相关阅读:
    SHELL
    终端如何输出彩色字体
    BTree和B+Tree详解
    博客项目----小功能模块
    python的学习之旅---Mysql数据库
    Python的学习之旅———协程
    python的学习之旅---信号量 定时器
    python的学习之旅---回调机制
    Python的学习之旅———线程 事件
    centos安装redis
  • 原文地址:https://www.cnblogs.com/qluzzh/p/10306285.html
Copyright © 2011-2022 走看看