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,不能显示多余的正确或错误提示
  • 相关阅读:
    Roce ofed 环境搭建与测试
    Ubuntu 1804 搭建NFS服务器
    Redhat 8.0.0 安装与网络配置
    Centos 8.1 安装与网络配置
    SUSE 15.1 系统安装
    VSpare ESXi 7.0 基本使用(模板、iso、SRIOV)
    VSpare ESXi 7.0 服务器安装
    open SUSE leap 15.1 安装图解
    KVM虚拟机网卡连接网桥
    GitHub Action一键部署配置,值得拥有
  • 原文地址:https://www.cnblogs.com/qluzzh/p/10306285.html
Copyright © 2011-2022 走看看