linux shell 脚本详解 | 服务器排障常用命令 | 创建窗口部件

注:shell 入门几篇合辑。


linux shell 脚本入门到实战详解

宝山的博客 已于 2023-01-01 21:57:19 修改

一、shell 入门简介

1.1 什么是shell

  • shell 脚本简介

为啥介绍shell

上次出了一篇 linux 命令详解,得到了很多小伙伴的认可,有部分粉丝私信我,让我出一份shell 编程。进过一段时间准备,花了2周时间,整理了一篇shell 入门到实战的博文,欢迎大家阅读,指点。

什么是shell

网上有很多shell 的概念介绍,其实都很官方化,如果对linux 命令很熟悉,那么编写shell 就不是一个难事,shell 本质上是 linux 命令,一条一条命令组合在一起,实现某一个目的,就变成了shell脚本。它从一定程度上 减轻了工作量,提高了工作效率。

官方化的shell 介绍

Shell 通过提示您输入,向操作系统解释该输入,然后处理来自操作系统的任何结果输出,简单来说Shell就是一个用户跟操作系统之间的一个命令解释器。

常见的shell 有哪些

Bourne Shell(/usr/bin/sh或/bin/sh)
Bourne Again Shell(/bin/bash)
C Shell(/usr/bin/csh)
K Shell(/usr/bin/ksh)
Shell for Root(/sbin/sh)

最常用的shell是Bash,也就是Bourne Again Shell。Bash由于易用和免费,在日常工作中被广泛使用,也是大多数Linux操作系统默认的Shell环境。

1.2 shell 编程注意事项

  • shell 编程有哪些注意事项
    • shell 命名:Shell脚本名称命名一般为英文、大写、小写,后缀以.sh 结尾
    • 不能使用特殊符号、空格
    • 见闻之意,名称要写的一眼可以看出功能
    • shell 编程 首行需要 #!/bin/bash 开头
    • shell 脚本 变量 不能以 数字、特殊符号开头,可以使用下划线—,但不能 用破折号 -

1.3 第一个shell 脚本 hello world

  • 创建一个伟大编程项目 —Hello World
  # 创建一个Helloword.sh 文件
  [root@aly_server01~]# touch Helloword.sh
  
  # 编辑Helloword.sh 文件
  [root@aly_server01~]# vim Helloword.sh
  
  [root@aly_server01~]# cat Helloword.sh
  #!/bin/bash
  # This is ower first shell
  # by author rivers 2021.09
  echo "hello world"
  [root@aly_server01~]#
  [root@aly_server01~]# ll Helloword.sh
  -rw-r--r-- 1 root root 85 Sep 20 22:26   Helloword.sh
  # 赋予执行权限
  [root@aly_server01~]# chmod o+x Helloword.sh
  # 运行helloword.sh 脚本
  [root@aly_server01~]# ./Helloword.sh
  hello world
  [root@aly_server01~]#

二、shell 环境变量讲解

2.1 shell 变量详解

  • 环境变量介绍

    # 什么是变量
    很多人可能会说,可以变化的量就是变量。但是发现很多汉语意思很强大,看的懂的字,却不一定可以理解它的意思。这里可以理解为 a = 1,同时还可以 a =2、a = 3 ,不同的值都可以复制给同一个 变量 a 。
    
    # 常见的3种变量
    Shell编程中变量分为三种,分别是系统变量、环境变量和用户变量,Shell变量名在定义时,首个字符必须为字母(a-z,A-Z),不能以数字开头,中间不能有空格,可以使用下划线(_),不能使用(-),也不能使用标点符号等。
    
    # 简单的变量介绍
    [root@keeplived_server~]# a=18
    [root@keeplived_server~]# echo $a
    18
    
    

2.2 shell 系统变量 介绍

  • 系统变量

    # Shell常见的变量之一系统变量,主要是用于对参数判断和命令返回值判断时使用,系统变量详解如下:
    
    $0 		当前脚本的名称;
    $n 		当前脚本的第n个参数,n=1,2,…9;
    $* 		当前脚本的所有参数(不包括程序本身)$# 		当前脚本的参数个数(不包括程序本身)$? 		令或程序执行完后的状态,返回0表示执行成功;
    $$ 		程序本身的PID号。
    
    

2.3 shell 环境变量 介绍

2.3.1 常见的系统环境变量
  • 环境变量介绍

    #Shell常见的变量之二环境变量,主要是在程序运行时需要设置,环境变量详解如下:
    
    PATH  		命令所示路径,以冒号为分割;
    HOME  		打印用户家目录;
    SHELL 		显示当前Shell类型;
    USER  		打印当前用户名;
    ID    		打印当前用户id信息;
    PWD   		显示当前所在路径;
    TERM  		打印当前终端类型;
    HOSTNAME    显示当前主机名;
    PS1         定义主机命令提示符的;
    HISTSIZE    历史命令大小,可通过 HISTTIMEFORMAT 变量设置命令执行时间;
    RANDOM      随机生成一个 032767 的整数;
    HOSTNAME    主机名
    
    

2.4 shell 用户环境变量 介绍

2.4.1 自定义shell环境变量
  • 用户自定义变量

    # 常见的变量之三用户变量,用户变量又称为局部变量,主要用在Shell脚本内部或者临时局部使用,系统变量详解如下:
    a=rivers 				       自定义变量A;
    Httpd_sort=httpd-2.4.6-97.tar  自定义变量N_SOFT;
    BACK_DIR=/data/backup/         自定义变量BACK_DIR;
    IPaddress=10.0.0.1			   自定义变量IP1;
    
    
2.4.2 echo 打印菜单栏
  • 使用echo 打印菜单栏,显示http-2.4安装过程

    \# echo 打印 httpd-2.4 安装步骤
    [root@web-server01~]# touch httpd_2.4_install.sh
    
    \# 赋予执行权限
    [root@web-server01~]# chmod o+x httpd_2.4_install.sh
    [root@web-server01~]# ./httpd_2.4_install.sh
    
    
2.4.3 shell 中彩色输出 helloworld
  • echo -e 扩展

    #!/bin/bash
    # This is echo color shell
    # by author rivers 2021.09-23
    # 字体颜色
    for i in {
          
          31..37}; do
    echo -e "\033[$i;40mHello world!\033[0m"
    done
    # 背景颜色
    for i in {
          
          41..47}; do
    echo -e "\033[47;${i}mHello world!\033[0m"
    done
    # 显示方式
    for i in {
          
          1..8}; do
    echo -e "\033[$i;31;40mHello world!\033[0m"
    done
    
    

三、shell 编程流程控制语句

3.1 if 条件语句介绍

3.1.1 常用的单/双分支
  • if 条件语句

    # If条件判断语句,通常以if开头,fi结尾。也可加入else或者elif进行多条件的判断
    
    # 单分支语句 ---比较大小
    	if (条件表达式);then
    		语句1
    	fi
    
    # 双分支if 语句
    	if (表达式)
    		语句1
    	else
    		语句2
    	fi
    
    # 多支条件语句 ---判断成绩
    	if (表达式)
    		语句1
    	elif
    		语句2
    	elif
    		语句2
    	fi
    
    
3.1.2 if 常见判断逻辑运算符详解
  • 常见逻辑判断运算符

    -f	 	判断文件是否存在 eg: if [ -f filename ];
    -d	 	判断目录是否存在 eg: if [ -d dir     ];
    -eq		等于,应用于整型比较 equal;
    -ne		不等于,应用于整型比较 not equal;
    -lt		小于,应用于整型比较 letter;
    -gt		大于,应用于整型比较 greater;
    -le		小于或等于,应用于整型比较;
    -ge 	大于或等于,应用于整型比较;
    -a		双方都成立(and) 逻辑表达式 –a 逻辑表达式;
    -o		单方成立(or) 逻辑表达式 –o 逻辑表达式;
    -z		空字符串;
    -x      是否具有可执行权限
    ||      单方成立;
    &&      双方都成立表达式。
    
    
3.1.3 使用单分支语句判断crond 进程是否在运行—案例
  • 判断 crond 服务是否运行

    #!/bin/bash
    # this is check crond
    # by author rivers on 2021-9.23
    
    # 定义一个变量名
    name=crond
    num=$(ps -ef|grep $name|grep -vc grep)
    if [ $num -eq 1 ];then
        echo "$num running!"
    else
        echo "$num is not running!"
    fi
    
    
3.1.4 判断系统目录是否存在 —案例
  • 判断系统目录是否存在

    #!/bin/bash
    # this is check directory
    # by author rivers on 2021-9.27
     if  [  !  -d  /data/rivers  -a  !  -d  /tmp/rivers  ];then
     mkdir  -p  /data/rivers  f
     i
    
    
3.1.5 多个条件判断学生分数等级 — 案例
  • 判断学生成绩等级

    # if 语句可以直接对命令状态进行判断,就省去了获取$?这一步!
      # 如果第一个条件符合就不再向下匹配
    #!/bin/bash
      # this check grade shell
      # by author rivers on 2021-09-27
    
      grade=$1
      if [ $grade -gt 90 ];then
        echo "Is's very good!"
      elif [ $grade -gt 70 ];then
        echo "Is's is good!"
    
      elif [ $grade -ge 60 ];then
        echo "pass"
    
      else
        echo "no pass"
      fi
    
    

3.2 for 循环语句介绍

  • for 循环语句

    #格式:for name [ [ in [ word ... ] ] ; ] do list ; done
      for 变量名 in 取值列表; do
        语句 1
      done
    
    
3.2.1 检查同一局域网 多台主机是否存活
  • 检查多台主机存活情况

    #!/bin/bash
    # check hosts is on/Off
    # by rivers on 20219-23
    
    Network=$1
    for Host in $(seq 1 254)
    do
    ping -c 1 $Network.$Host > /dev/null && result=0 || result=1
    
    if [ "$result" == 0 ];then
      echo -e "\033[32;1m$Network.$Host is up \033[0m"
      echo "$Network.$Host" >> /tmp/up.txt
    
    else
      echo -e "\033[;31m$Network.$Host is down \033[0m"
      echo "$Network.$Host" >> /tmp/down.txt
    fi
    done
    
    

3.3 while 循环语句介绍

  • while 循环语句

    # While循环语句与for循环功能类似,主要用于对某个数据域进行循环读取、对文件进行遍历,通常用于需要循环某个文件或者列表,满足循环条件会一直循环,不满足则退出循环,其语法格式以while…do开头,done结尾与
    #while 关联的还有一个 until 语句,它与 while 不同之处在于,是当条件表达式为 false 时才循环,实际使用中比较少,这里不再讲解。
    
    while  (表达式)
    do
      语句1
    done
    
    
  • break 和 continue 语句

    # break 和 continue 语句
      break 是终止循环。
      continue 是跳出当前循环。
    #示例 1:在死循环中,满足条件终止循环
    while true; do
      let N++
      if [ $N -eq 5 ]; then
        break
    fi
      echo $N
    done
    输出: 1 2 3 4
    
    #示例 2:举例子说明 continue 用法
    N=0
    while [ $N -lt 5 ]; do
      let N++
    if [ $N -eq 3 ]; then
      continue
    fi
      echo $N
    done
    
    输出: 1 2 4
    
    # 打印 1-100 数字
    i=0
    while ((i<=100))
    do
            echo  $i
            i=`expr $i + 1`
    done
    
    
3.3.1 While循环求1-100的总和 —案例
  • 求1-100的总和

    #!/bin/bash
    # by author rivers on 2021-9-27
    j=0
    i=1
    while ((i<=100))
    do
         j=`expr $i + $j`
         ((i++))
    done
    echo $j
    
    
3.3.2 每10秒循环判断一次 hbs用户是否登录系统 —案例
  • 每 10秒 循环判断系统登录

    [root@web-server01~/script]# vim login.sh
    #!/bin/bash
    #Check File to change.
    #By author rivers 2021-9-27
    USERS="hbs"
    while true
    do
            echo "The Time is `date +%F-%T`"
            sleep 10
            NUM=`who|grep "$USERS"|wc -l`
            if [[ $NUM -ge 1 ]];then
                    echo "The $USERS is login in system."
            fi
    done
    
    

3.4 case 选择语句介绍

  • case 选择语句

    #Case选择语句,主要用于对多个选择条件进行匹配输出,与if elif语句结构类似,通常用于脚本传递输入参数,打印出输出结果及内容,其语法格式以Case…in开头,esac结尾。语法格式如下:
    case 模式名  in
      模式 1)
        命令
        ;;
      模式 2)
        命令
        ;;
    *)
    不符合以上模式执行的命令
    esac
    # 每个模式必须以右括号结束,命令结尾以双分号结束。
    
    
3.4.1 使用case 编写一个 httpd 服务启动脚本
  • 编写 http服务启动脚本

    [root@web-server01~/script]# vim httpd_start.sh
    # check http server start|stop|starus
    # by author rivers on 2021-9-27
    while true
    do
        echo -e "
        \033[31m start \033[0m
        \033[32m stop \033[0m
        \033[33m status \033[0m
        \033[34m quit \033[0m
    "
    read -p "请输入选择start|stop|quit:" char
    case $char in
    start)
        systemctl start httpd && echo "httpd服务已经开启" || echo "开启失败"
    ;;
    stop)
        systemctl stop httpd && echo "httpd服务已经关闭" || echo "关闭失败"
    ;;
    restart)
        systemctl restart httpd && echo "httpd服务已经重启" || echo "重启失败
    "
    ;;
    status)
        systemctl status httpd && echo -e "
            httpd 的服务状态
    
    ;;
    quit)
    
    

3.5 select 选择语句介绍

  • select 选择语句

    #select 是一个类似于 for 循环的语句
    #Select语句一般用于选择,常用于选择菜单的创建,可以配合PS3来做打印菜单的输出信息,其语法格式以select…in do开头,done结尾:
    
    select i in (表达式)
    do
    语句
    done
    
    # 选择mysql 版本
    #!/bin/bash
    # by author rivers on 2021-9-27
    PS3="Select a number: "
    while true; do
    select mysql_version in 5.1 5.6 quit;
     do
      case $mysql_version in
      5.1)
        echo "mysql 5.1"
          break
          ;;
      5.6)
        echo "mysql 5.6"
           break
           ;;
      quit)
        exit
        ;;
      *)
        echo "Input error, Please enter again!"
          break
    esac
     done
    done
    
    
3.5.1 使用select 打印lnmp 菜单栏 —案例
  • 打印lnmp选择菜单

    #!/bin/bash
    #by author rivers on 2021-9-27
    PS3="Please enter you select install menu:"
    select i in http php mysql quit
    do
    case $i in
            http)
            echo -e "
                    \033[31m Test Httpd \033[0m"
            ;;
            php)
            echo  -e "\033[32m Test PHP\033[0m"
            ;;
            mysql)
            echo -e "\033[33m Test MySQL.\033[0m"
            ;;
            quit)
            echo -e "\033[32m The System exit.\033[0m"
            exit
    esac
    done
    
    

3.6 shell 函数、数组 编程 实战

  • 函数

    # Shell允许将一组命令集或语句形成一个可用块,这些块称为Shell函数,Shell函数的用于在于只需定义一次,后期随时使用即可,无需在Shell脚本中添加重复的语句块,其语法格式以function name(){开头,以}结尾。
    
    # Shell编程函数默认不能将参数传入()内部,Shell函数参数传递在调用函数名称传递,例如name args1 args2。
    
    # 函数语法
    func() {
          
          
    command1
    command1
    ……
    }
    fun  # 直接调用函数名
    # Shell 函数很简单,函数名后跟双括号,再跟双大括号。通过函数名直接调用,不加小括号。
    #!/bin/bash
    func() {
          
          
    VAR=$((1+1))
    return $VAR
    echo "This is a function."
    }
    func
    echo $?
    # bash test.sh
    2
    
    
  • 数组

    # 数组是相同类型的元素按一定顺序排列的集合。
    格式:array=(元素 1 元素 2 元素 3 ...)
    用小括号初始化数组,元素之间用空格分隔。
     定义方法 1:初始化数组 array=(a b c)
     定义方法 2:新建数组并添加元素 array[下标]=元素
     定义方法 3:将命令输出作为数组元素array=($(command))
    
    
3.6.1 定义一个httpd 安装的函数 —案例
  • 创建apache软件安装函数

    [root@web-server01~/script]# vim xx.sh
    #!/bin/bash
    #auto install apache
    #By author rivers 2021-09-27
    #Httpd define path variable
    FILES=httpd-2.2.31.tar.bz2
    LES_DIR=httpd-2.2.31
    URL=http://mirrors.cnnic.cn/apache/httpd/
    PREFIX=/usr/local/apache2/
    function Apache_install ()
    {
          
          
    #Install httpd web server
    if [[ "$1" -eq "1" ]];then
            wget -c $URL/$FILES &&  tar -jxvf $FILES && cd $FILES_DIR &&./configure
            if [ $? -eq 0 ];then
                    make && make install
                    echo -e "\n\033[32m--------------------------------------------
                    echo -e "\033[32mThe $FILES_DIR Server Install Success !\033[0m
            else
                    echo -e "\033[32mThe $FILES_DIR Make or Make install ERROR,Plea
                    exit 0
            fi
    fi
    }
    Apache_install 1
    # 调用函数,传参为1
    
    
3.6.2 遍历数组元素 — 案例
  • 遍历数组元素

    #方法 1:
    #!/bin/bash
    IP=(10.0.0.1 10.0.0.2 10.0.0.3)
    for ((i=0;i<${#IP[*]};i++)); do
    echo ${IP[$i]}
    done
    # bash test.sh
    10.0.0.1
    10.0.0.2
    10.0.0.3
    
    #方法 2:
    #!/bin/bash
    IP=(10.0.0.1 10.0.0.2 10.0.0.3)
    for   IP   in ${IP[*]}; do
    echo $IP
    done
    
    

四、shell 编程实战 案例

4.1 shell 脚本实战之 系统备份脚本 —案例

  • Tar工具全备、增量备份网站,Shell脚本实现自动打包备份

    #!/bin/bash
    #Auto Backup Linux System Files
    #by author rivers on 2021-09-28
    
    SOURCE_DIR=(
        $*
    )
    TARGET_DIR=/data/backup/
    YEAR=`date +%Y`
    MONTH=`date +%m`
    DAY=`date +%d`
    WEEK=`date +%u`
    A_NAME=`date +%H%M`
    FILES=system_backup.tgz
    CODE=$?
    if
        [ -z "$*" ];then
        echo -e "\033[32mUsage:\nPlease Enter Your Backup Files or Directories\n--------------------------------------------\n\nUsage: { $0 /boot /etc}\033[0m"
        exit
    fi
    #Determine Whether the Target Directory Exists
    if
        [ ! -d $TARGET_DIR/$YEAR/$MONTH/$DAY ];then
        mkdir -p $TARGET_DIR/$YEAR/$MONTH/$DAY
        echo -e "\033[32mThe $TARGET_DIR Created Successfully !\033[0m"
    fi
    #EXEC Full_Backup Function Command
    Full_Backup()
    {
          
          
    if
        [ "$WEEK" -eq "7" ];then
        rm -rf $TARGET_DIR/snapshot
        cd $TARGET_DIR/$YEAR/$MONTH/$DAY ;tar -g $TARGET_DIR/snapshot -czvf $FILES ${SOURCE_DIR[@]}
        [ "$CODE" == "0" ]&&echo -e  "--------------------------------------------\n\033[32mThese Full_Backup System Files Backup Successfully !\033[0m"
    fi
    }
    #Perform incremental BACKUP Function Command
    Add_Backup()
    {
          
          
       if
            [ $WEEK -ne "7" ];then
            cd $TARGET_DIR/$YEAR/$MONTH/$DAY ;tar -g $TARGET_DIR/snapshot -czvf $A_NAME$FILES ${SOURCE_DIR[@]}
            [ "$CODE" == "0" ]&&echo -e  "-----------------------------------------\n\033[32mThese Add_Backup System Files $TARGET_DIR/$YEAR/$MONTH/$DAY/${YEAR}_$A_NAME$FILES Backup Successfully !\033[0m"
       fi
    }
    sleep 3
    Full_Backup;Add_Backup
    
    

4.2 shell 脚本 实战 之收集系统信息 —案例

  • Shell脚本实现服务器信息自动收集

    cat <<EOF
    ++++++++++++++++++++++++++++++++++++++++++++++
    ++++++++Welcome to use system Collect+++++++++
    ++++++++++++++++++++++++++++++++++++++++++++++
    EOF
    ip_info=`ifconfig |grep "Bcast"|tail -1 |awk '{print $2}'|cut -d: -f 2`
    cpu_info1=`cat /proc/cpuinfo |grep 'model name'|tail -1 |awk -F: '{print $2}'|sed 's/^ //g'|awk '{print $1,$3,$4,$NF}'`
    cpu_info2=`cat /proc/cpuinfo |grep "physical id"|sort |uniq -c|wc -l`
    serv_info=`hostname |tail -1`
    disk_info=`fdisk -l|grep "Disk"|grep -v "identifier"|awk '{print $2,$3,$4}'|sed 's/,//g'`
    mem_info=`free -m |grep "Mem"|awk '{print "Total",$1,$2"M"}'`
    load_info=`uptime |awk '{print "Current Load: "$(NF-2)}'|sed 's/\,//g'`
    mark_info='BeiJing_IDC'
    echo -e "\033[32m-------------------------------------------\033[1m"
    echo IPADDR:${ip_info}
    echo HOSTNAME:$serv_info
    echo CPU_INFO:${cpu_info1} X${cpu_info2}
    echo DISK_INFO:$disk_info
    echo MEM_INFO:$mem_info
    echo LOAD_INFO:$load_info
    echo -e "\033[32m-------------------------------------------\033[0m"
    echo -e -n "\033[36mYou want to write the data to the databases? \033[1m" ;read ensure
    
    if      [ "$ensure" == "yes" -o "$ensure" == "y" -o "$ensure" == "Y" ];then
            echo "--------------------------------------------"
            echo -e  '\033[31mmysql -uaudit -p123456 -D audit -e ''' "insert into audit_system values('','${ip_info}','$serv_info','${
    cpu_info1} X${cpu_info2}','$disk_info','$mem_info','$load_info','$mark_info')" ''' \033[0m '
            mysql -uroot -p123456 -D test -e "insert into audit_system values('','${ip_info}','$serv_info','${cpu_info1} X${cpu_info2}
    ','$disk_info','$mem_info','$load_info','$mark_info')"
    else
            echo "Please wait,exit......"
            exit
    fi
    
    

4.3 shell 脚本实战 之 一键部署 lnmp 架构 — 案例

  • 批量部署lnmp 架构

    [root@web-server01~/script]# vim lnmp.sh 
    #!/bin/bash
    #install lnmp
    #by author rivers on 2021-9-28
    
    # nginx 环境准备
    Nginx_url=https://nginx.org/download/nginx-1.20.1.tar.gz
    Nginx_prefix=/usr/local/nginx
    
    # mysql 环境准备
    Mysql_version=mysql-5.5.20.tar.gz
    Mysql_dir=mysql-5.5.20
    Mysql_url=https://downloads.mysql.com/archives/get/p/23/file/mysql-5.5.20.tar.gz
    Mysql_prefix=/usr/local/mysql/
    
    # php 环境准备
    Php_version=php-7.2.10.tar.gz
    Php_prefix=/usr/local/php-7.2.10/
    
    
    function nginx_install(){
          
          
    
    if [[ "$1" -eq "1" ]];then
            if [ $? -eq 0 ];then
                    make && make install
            fi
    
    fi
    }
    
    
    
    function mysql_install(){
          
          
    if [[ "$1" -eq "2" ]];then
    -DMYSQL_UNIX_ADDR=/tmp/mysql.sock \
    -DMYSQL_DATADIR=/data/mysql \
    -DSYSCONFDIR=/etc \
    -DMYSQL_USER=mysql \
    -DMYSQL_TCP_PORT=3306 \
    -DWITH_XTRADB_STORAGE_ENGINE=1 \
    -DWITH_INNOBASE_STORAGE_ENGINE=1 \
    -DWITH_PARTITION_STORAGE_ENGINE=1 \
    -DWITH_BLACKHOLE_STORAGE_ENGINE=1 \
    -DWITH_MYISAM_STORAGE_ENGINE=1 \
    -DWITH_READLINE=1 \
    -DENABLED_LOCAL_INFILE=1 \
    -DWITH_EXTRA_CHARSETS=1 \
    -DDEFAULT_CHARSET=utf8 \
    -DDEFAULT_COLLATION=utf8_general_ci \
    -DEXTRA_CHARSETS=all \
                    echo -e "\033[32mThe $Mysql_dir Server Install Success !\033[0m"
            else
                    echo -e "\033[32mThe $Mysql_dir Make or Make install ERROR,Please Check......"
                    exit 0
    fi
    /bin/cp support-files/my-small.cnf  /etc/my.cnf
    /bin/cp support-files/mysql.server /etc/init.d/mysqld
    chmod +x /etc/init.d/mysqld
    chkconfig --add mysqld
    chkconfig mysqld on
    fi
    }
    
    
    function php_install(){
          
          
    if [[ "$1" -eq "3" ]];then
            if [ $? -eq 0 ];then
                    make ZEND_EXTRA_LIBS='-liconv' && make install
    if [[ "$1" -eq "3" ]];then
     wget $Php_url && tar xf $Php_version && cd $Php_dir && yum install   bxml2* bzip2* libcurl*  libjpeg* libpng* freetype* gmp* libm
    crypt* readline* libxslt* -y && ./configure --prefix=$Php_prefix --disable-fileinfo --enable-fpm --with-config-file-path=/etc --wi
      -config-file-scan-dir=/etc/php.d --with-openssl --with-zlib --with-curl --enable-ftp --with-gd --with-xmlrpc --with-jpeg-dir --w
    ith-png-dir --with-freetype-dir --enable-gd-native-ttf --enable-mbstring --with-mcrypt=/usr/local/libmcrypt --enable-zip --enable-
    mysqlnd --with-mysqli=mysqlnd --with-pdo-mysql=mysqlnd --with-mysql-sock=/var/lib/mysql/mysql.sock --without-pear --enable-bcmath
            if [ $? -eq 0 ];then
                    make ZEND_EXTRA_LIBS='-liconv' && make install
                    echo -e "\n\033[32m-----------------------------------------------\033[0m"
                    echo -e "\033[32mThe $Php_version Server Install Success !\033[0m"
            else
                    echo -e "\033[32mThe $Php_version Make or Make install ERROR,Please Check......"
                    exit 0
            fi
    fi
    }
    
    
    PS3="Please enter you select install menu:"
    select i in nginx mysql php quit
    do
    "lnmp.sh" 113L, 3516C written                                                                                   
    [root@web-server01~/script]# vim lnmp.sh 
    chkconfig --add mysqld
    chkconfig mysqld on
    fi
    }
    
    
    function php_install(){
          
          
    if [[ "$1" -eq "3" ]];then
            if [ $? -eq 0 ];then
                    make ZEND_EXTRA_LIBS='-liconv' && make install
                    echo -e "\n\033[32m-----------------------------------------------\033[0m"
                    echo -e "\033[32mThe $Php_version Server Install Success !\033[0m"
            else
                    echo -e "\033[32mThe $Php_version Make or Make install ERROR,Please Check......"
                    exit 0
            fi
    fi
    }
    
    
    PS3="Please enter you select install menu:"
    select i in nginx mysql php quit
    do
    
    case $i in
            nginx)
            nginx_install 1
            ;;
            mysql)
            mysql_install 2
            ;;
            php)
            php_install 3
            ;;
            quit)
            exit
    esac
    done
    
    
    
    
    
    

总结

shell 是工作中很重要的一部分,在工作中充当着重要的角色。企业生产环境中,服务器规模成百上千,如果依靠人工去维护和管理是非常吃力的,基于Shell编程脚本管理和维护服务器变得简单、从容,而且对企业自动化运维之路的建设起到极大的推动作用。

所以,不管是看到哪里的书籍、资料、还是视频,每个老师讲的侧重点都不一样,但是基础是一样的,要想学号shell,需要反复动手写,思考,理解shell 的精髓,才能掌握shell ,写好shell。


服务器排障常用命令

宝山的博客 已于 2022-11-17 23:11:07 修改

1.ifconfig命令

  • inux ifconfig命令用于显示或设置网络设备。
  • ifconfig可设置网络设备的状态,或是显示目前的设置。
# 1. ifconfig 查看IP地址===>(ip add命令)
[root@rivers ~]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.10.103  netmask 255.255.255.0  broadcast 192.168.10.255
        inet6 fe80::313d:5ec5:2360:b413  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:73:a6:4f  txqueuelen 1000  (Ethernet)
        RX packets 72197  bytes 61229101 (58.3 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 50277  bytes 3210398 (3.0 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

 第一行: # UP 标识网络接口为 启用状态(down关闭状态)
 	    # Broadcast广播
 	    # running 网卡设备以连接
 	    # multicast 支持组播
 	    # mtu 数据最大传输单元

 第二行 : # ip地址、子网掩码、广播地址
 第三行 : # ipv6 地址
 第四行 : #  Ethernet 以太网表示连接类型
 		 # ether 标识为MAC地址
 第五行 : # 接手数据包个数,大小统计信息 
 第六行 : # 异常接收包的个数,如 丢包两、错误等
 第七行 : # 发送数据包个数、大小统计信息
 第八行 : # 发送数据包的个数,如丢包量、错误等
 
 ifconfig
#打开(up)或关闭(down)适配器
ifconfig <网络名> <up|down>
[root@rivers ~]# ifconfig ens33 up
[root@rivers ~]# ifconfig ens33 down
#为适配器分配IP地址:
ifconfig <网络名> <ip地址>   重启失效

[root@rivers ~]# ifconfig ens33 192.168.10.103
#为适配器分配第二个IP地址:
ifconfig <网络名:实例数> <ip地址>

2.ping 命令

Linux ping 命令用于检测主机。

执行 ping 指令会使用 ICMP 传输协议,发出要求回应的信息,若远端主机的网络功能没有问题,就会回应该信息,因而得知该主机运作正常。

> # linux 命令参数
> ping [-dfnqrRv][-c<完成次数>][-i<间隔秒数>][-I<网络界面>][-l<前置载入>][-p<范本样式>][-s<数据包大小>][-t<存活数值>][主机名称或IP地址]
> # windows 命令参数:
> ping (ip地址或主机名) (-t) (-a) (-n count) (-l size) 
> 	-t不停地向目标主机发送数据; 
> 	-a 以ip地址格式来显示目标主机的网络地址 ; 	
> 	-n count 指定要ping多少次,具体次数由count来指定 ; 
> 	-l size 指定发送到目标主机的数据包的大小。 
> 
> ping 
> netsh wlan show profile name=BJTX key=clear
> 
[root@rivers ~]# ping www.baidu.com -c 1
PING www.a.shifen.com (39.156.66.14) 56(84) bytes of data.
64 bytes from 39.156.66.14 (39.156.66.14): icmp_seq=1 ttl=128 time=5.28 ms


Usage: ping [-aAbBdDfhLnOqrRUvV64] [-c count] [-i interval] [-I interface]
            [-m mark] [-M pmtudisc_option] [-l preload] [-p pattern] [-Q tos]
            [-s packetsize] [-S sndbuf] [-t ttl] [-T timestamp_option]
            [-w deadline] [-W timeout] [hop1 ...] destination

[root@rivers ~]# ping www.baidu.com -c 2 -I ens33  -s 100 
PING www.a.shifen.com (39.156.66.14) from 192.168.10.103 ens33: 100(128) bytes of data.
108 bytes from 39.156.66.14 (39.156.66.14): icmp_seq=1 ttl=128 time=5.84 ms
108 bytes from 39.156.66.14 (39.156.66.14): icmp_seq=2 ttl=128 time=6.57 ms
[root@rivers ~]# ping -i 3 -s 1000 -c 1000  www.baidu.com   //间隔3秒 发送1000个包,
PING www.a.shifen.com (110.242.68.3) 100(128) bytes of data.
108 bytes from 110.242.68.3 (110.242.68.3): icmp_seq=1 ttl=128 time=11.1 ms
108 bytes from 110.242.68.3 (110.242.68.3): icmp_seq=2 ttl=128 time=28.8 ms
……

3.arp命令

  • arp命令的英文全拼“Address Resolution Protocol” 。该命令用于操作主机的arp缓存,它可以显示arp缓存中的所有条目、删除指定的条目或者添加静态的ip地址与MAC地址对应关系。
  • 常用参数:
  • -n 以数字方式显示
  • -i 指定网络接口
  • -d 删除arp记录
显示本机arp缓存中所有记录:
[root@rivers ~]# arp
Address                  HWtype  HWaddress           Flags Mask           Iface
gateway                  ether   00:50:56:ff:3a:57     C                 ens33
192.168.10.1               ether   00:50:56:c0:00:08     C                 ens33
以数字方式显示指定主机arp缓存条目:
[root@rivers ~]# arp -n
Address                  HWtype  HWaddress           Flags Mask           Iface
192.168.10.2               ether   00:50:56:ff:3a:57      C                ens33
192.168.10.1               ether   00:50:56:c0:00:08      C                 ens33
删除接口ens33上的192.168.10.2的arp表中的项:
[root@rivers ~]#  arp -i ens33 -d 192.168.10.2
使用ens33的MAC地址回答eth0上的192.168.10.2的arp请求
[root@rivers ~]# arp -i ens33 -Ds 192.168.10.2 ens33 pub 

4.arping命令

  • arping命令作用是使用arp数据包,通过ping命令检查来测试网络。arping命令能够测试一个ip地址是否是在网络上已经被使用,并能够获取更多设备信息。功能类似于ping。
  • 由于arping命令基于ARP广播机制,
  • 所以arping命令只能测试同一网段或子网的网络主机的连通性
  • ping命令则是基于ICMP协议,是可以路由的,所以使用ping命令可以测试任意网段的主机网络连通性。
  • 常用参数:
  • -D 重复地址检测模式
  • -A 更新邻近主机的ARP缓存
  • -c 指定发送arp 请求个数
  • -l 指定arp请求报文的网络接口
  • -s 指定发送arp请求数据包的源地址
  • -U 更新邻近主机的ARP缓存
测试目标主机的存活状态:
[root@rivers ~]# arping -f 192.168.10.1
ARPING 192.168.10.1 from 192.168.10.102 ens33
Unicast reply from 192.168.10.1 [00:50:56:C0:00:08]  0.689ms
Sent 1 probes (1 broadcast(s))
Received 1 response(s)
向目标主机发送3次(指定次数)ARP请求报文:
[root@rivers ~]# arping -c 3 192.168.10.1
ARPING 192.168.10.1 from 192.168.10.102 ens33
Unicast reply from 192.168.10.1 [00:50:56:C0:00:08]  0.769ms
Unicast reply from 192.168.10.1 [00:50:56:C0:00:08]  0.648ms
Unicast reply from 192.168.10.1 [00:50:56:C0:00:08]  0.675ms
Sent 3 probes (1 broadcast(s))
Received 3 response(s)

5. telnet 命令

  • telnet命令的功能是用于控制远程设备
  • 执行telnet指令开启终端机阶段作业,并登入远端主机。
  • telnet命令可以帮助你从这台路由器远程登陆到远端开启了telnet服务的设备,包括路由器、交换机、linux服务器等,并且配置当前路由器的telnet服务。
  • 常用参数
  • -d 启动排错模式
  • -l 登录用户名
  • -a 尝试自动登入远端系统
指定登录端口
[root@rivers ~]# telnet 192.168.10.2 19880
Trying 192.168.10.2...
指定登录用户名
[root@rivers ~]# telnet -l admin 192.168.10.2 

7. SSH 命令

  • ssh命令的功能是用于安全的远程连接服务器主机系统,作为openssh套件中的客户端连接工具,ssh命令可以让我们轻松的基于ssh加密协议进行远程主机访问,从而实现对远程服务器的管理工作。
  • 常用参数
  • -1/2 强制是使用ssh 协议 V1、V2 版本
  • -4/6 强制使用ipv4、ipv6地址
  • -A 开启认证代理连接转发功能
  • -a 关闭认证代理连接转发功能
  • -l 指定连接远程服务器的登录用户名
  • -p 指定远程服务器上的端口
使用指定的用户身份登录远程服务器主机系统:
[root@rivers ~]# ssh -l linuxprobe 192.168.10.2 
登录远程服务器主机系统后执行一条命令:
[root@rivers ~]# ssh 192.168.10.2 "free -m"
强制使用v1版本的ssh加密协议连接远程服务器主机:
[root@rivers ~]# ssh -1 192.168.10.2

8. route 相关命令

route命令的功能是用于显示与设置路由信息,是Linux系统中常用的静态路由配置工具。要想让两台处在不同子网之间的服务器能够通信,需要有一个跨网段的路由器来连接它们,并用route命令为其设置路由信息,提供软硬件的支撑。

  • 常用参数有:
  • -A 设置地址类型(默认IPV4)
  • -n 以数字形式显示IP地址
  • -net
  • -host
  • add 增加指定的路由记录
  • del 删除指定的路由记录
  • gw 设置默认网关
  • dev 路由记录所表示的网络接口
显示当前路由
[root@localhost ~]# route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
192.168.10.0    0.0.0.0         255.255.255.0   U     100    0        0 ens160
192.168.122.0   0.0.0.0         255.255.255.0   U     0      0        0 virbr0
添加一条指定的路由信息
[root@localhost ~] route add -net 192.168.10.0 netmask 255.255.255.0 dev ens160
删除一条网络路由
[root@localhost ~]# route del -net 192.168.10.0 netmask 255.255.255.0 dev ens160
增加/删除默认网关
route add/del default gw 192.168.10.1
获取192.168.10.2 路由
[root@rivers ~]# ip route get 192.168.10.2
192.168.10.2 dev ens33 src 192.168.10.102 
    cache 
[root@rivers ~]# 
查看路由信息
[root@rivers ~]# ip route show
default via 192.168.10.2 dev ens33 proto static metric 100 
192.168.10.0/24 dev ens33 proto kernel scope link src 192.168.10.102 metric 100 
设置永久路由的方法
#  在/etc/rc.local里添加

9. traceroute 命令

  • traceroute命令用于追踪数据包在网络上的传输时的全部路径,它默认发送的数据包大小是40字节。通过traceroute我们可以知道信息从你的计算机到互联网另一端的主机是走的什么路径。当然每次数据包由某一同样的出发点(source)到达某一同样的目的地(destination)走的路径可能会不一样,但基本上来说大部分时候所走的路由是相同的。
  • traceroute通过发送小的数据包到目的设备直到其返回,来测量其需要多长时间。一条路径上的每个设备traceroute要测3次。输出结果中包括每次测试的时间(ms)和设备的名称(如有的话)及其ip地址。
  • 常用参数:
  • -n 不显示主机名
  • -m 设置跳数 设置检测数据包的最大存活数值TTL的大小
  • -q 设置检测包的数量
  • -f <存活数值> 设置第一个检测数据包的存活数值TTL的大小
追踪本地数据包到www.baidu.com的传输路径
[root@rivers ~]# traceroute www.baidu.com
显示IP地址,不查主机名 :
[root@rivers ~]# traceroute www.baidu.com -n -m 1
traceroute to www.baidu.com (39.156.66.14), 1 hops max, 60 byte packets
 1  192.168.10.2  0.088 ms  0.053 ms  0.044 ms
把探测包的个数设置为值100:
[root@rivers ~]# traceroute www.baidu.com -q 100
跳数设置,设置2跳 -m
root@rivers ~]# traceroute www.baidu.com -m 2
traceroute to www.baidu.com (39.156.66.14), 2 hops max, 60 byte packets
 1  gateway (192.168.10.2)  0.109 ms  0.044 ms  0.040 ms
 2  * * *
把对外发探测包的等待响应时间设置为3秒:-w
[root@rivers ~]# traceroute www.baidu.com -q 10 -m 1 -w 3
traceroute to www.baidu.com (39.156.66.18), 1 hops max, 60 byte packets
 1  gateway (192.168.10.2)  0.094 ms  0.091 ms  0.043 ms  0.080 ms  0.040 ms  0.084 ms  0.041 ms  0.040 ms  0.051 ms  0.057 ms

10. tcpdump 命令

  • tcpdump命令的功能是用于监听网络流量,是一款数据嗅探工具,Linux系统中常用的数据抓包软件,能够记录所有经过服务器的数据包信息,需要使用管理员身份执行。
  • tcpdump和ethereal可以用来获取和分析网络通讯活动,他们都是使用libpcap库来捕获网络封包的。
  • 可以使用这些工具来探究网络相关问题。你可以发现TCP/IP重发、窗口大小的缩放、名字解析的问题、网络配置错误等。
  • 常用参数
参数介绍:
-A 以ASCII格式打印出所有分组,并将链路层的头最小化。
-c 在收到指定的数量的分组后,tcpdump就会停止。
-C 在将一个原始分组写入文件之前,检查文件当前的大小是否超过了参数file_size
中指定的大小。如果超过了指定大小,则关闭当前文件,然后在打开一个新的文件。参数 file_size
的单位是兆字节(是1,000,000字节,而不是1,048,576字节)。
-d 将匹配信息包的代码以人们能够理解的汇编格式给出。
-dd 将匹配信息包的代码以c语言程序段的格式给出。
-ddd 将匹配信息包的代码以十进制的形式给出。
-D 打印出系统中所有可以用tcpdump截包的网络接口。
-e 在输出行打印出数据链路层的头部信息。
-E 用spi@ipaddr algo:secret解密那些以addr作为地址,并且包含了安全参数索引值spi的IPsec ESP分组。
-f 将外部的Internet地址以数字的形式打印出来。
-F 从指定的文件中读取表达式,忽略命令行中给出的表达式。
-i 指定监听的网络接口。
-l 使标准输出变为缓冲行形式。
-L 列出网络接口的已知数据链路。
-m 从文件module中导入SMI MIB模块定义。该参数可以被使用多次,以导入多个MIB模块。
-M 如果tcp报文中存在TCP-MD5选项,则需要用secret作为共享的验证码用于验证TCP-MD5选选项摘要(详情可参考RFC 2385)。
-n 不把网络地址转换成名字。
-N 不输出主机名中的域名部分。例如,link.linux265.com 只输出link。
-t 在输出的每一行不打印时间戳。
-O 不运行分组分组匹配(packet-matching)代码优化程序。
-P 不将网络接口设置成混杂模式。
-q 快速输出。只输出较少的协议信息。
-r 从指定的文件中读取包(这些包一般通过-w选项产生)。
-S 将tcp的序列号以绝对值形式输出,而不是相对值。
-s 从每个分组中读取最开始的snaplen个字节,而不是默认的68个字节。
-T 将监听到的包直接解释为指定的类型的报文,常见的类型有rpc远程过程调用)和snmp(简单网络管理协议;)。
-t 不在每一行中输出时间戳。
-tt 在每一行中输出非格式化的时间戳。
-ttt 输出本行和前面一行之间的时间差。
-tttt 在每一行中输出由date处理的默认格式的时间戳。
-u 输出未解码的NFS句柄。
-v 输出一个稍微详细的信息,例如在ip包中可以包括ttl和服务类型的信息。
-vv 输出详细的报文信息。
-w 直接将分组写入文件中,而不是不分析并打印出来。
-x 以16进制数形式显示每一个报文 (去掉链路层报头) . 可以显示较小的完整报文, 否则只显示snaplen个字节.
-xx 以16进制数形式显示每一个报文(包含链路层包头)。
-X 以16进制和ASCII码形式显示每个报文(去掉链路层报头)。
-XX 以16进制和ASCII吗形式显示每个报文(包含链路层报头)。
-y 设置tcpdump 捕获数据链路层协议类型
-Z 使tcpdump 放弃自己的超级权限(如果以root用户启动tcpdump, tcpdump将会有超级用户权限), 并把当前tcpdump的用户ID设置为user, 组ID设置为user首要所属组的ID

01、抓取所有网络包,并在terminal中显示抓取的结果,将包以十六进制的形式显示。
tcpdump 
02、抓取所有的网络包,并存到 result.cap 文件中。
tcpdump -w result.cap
03、抓取所有的经过eth0网卡的网络包,并存到 result.cap 文件中。
tcpdump -i eth0 -w result.cap
04、抓取源地址是192.168.1.100的包,并将结果保存到 result.cap 文件中。
tcpdump src host 192.168.1.100 -w result.cap 
05、抓取地址包含是192.168.1.100的包,并将结果保存到 result.cap 文件中。
tcpdump host 192.168.1.100 -w result.cap 
06、抓取目的地址包含是192.168.1.100的包,并将结果保存到 result.cap 文件中。
tcpdump dest host 192.168.1.100 -w result.cap 
07、抓取主机地址为 192.168.1.100 的数据包
tcpdump -i eth0 -vnn host 192.168.1.100
08、抓取包含192.168.1.0/24网段的数据包
tcpdump -i eth0 -vnn net 192.168.1.0/24
09、抓取网卡eth0上所有包含端口22的数据包
tcpdump -i eth0 -vnn port 22
10、抓取指定协议格式的数据包,协议格式可以是「udp,icmp,arp,ip」中的任何一种,例如以下命令:
tcpdump udp  -i eth0 -vnn
11、抓取经过 eth0 网卡的源 ip192.168.1.100 数据包,src参数表示源。
tcpdump -i eth0 -vnn src host 192.168.1.100
12、抓取经过 eth0 网卡目的 ip192.168.1.100 数据包,dst参数表示目的。
 tcpdump -i eth0 -vnn dst host 192.168.1.100
13、抓取源端口是22的数据包
tcpdump -i eth0 -vnn src port 22
14、抓取源ip是 192.168.1.100 且目的ip端口是22的数据包
tcpdump -i eth0 -vnn src host 192.168.1.100 and dst port 22
15、抓取源ip是192.168.1.100或者包含端口是22的数据包
tcpdump -i eth0 -vnn src host 192.168.1.100 or port 22
16、抓取源ip是192.168.1.100且端口不是22的数据包
tcpdump -i eth0 -vnn src host 192.168.1.100 and not port 22
17、抓取源ip是192.168.1.100且目的端口是22,或源ip是192.168.1.102且目的端口是80的数据包。
tcpdump -i eth0 -vnn ( src host 192.168.1.100 and dst port 22 ) or ( src host 192.168.1.102 and dst port 80 )
18、把抓取的数据包记录存到/tmp/result文件中,当抓取100个数据包后就退出程序。
tcpdump –i eth0 -vnn -w /tmp/result -c 100
19、从/tmp/result记录中读取tcp协议的数据包
tcpdump -i eth0  tcp  -vnn -r /tmp/result
20、想要截获所有192.168.1.100 的主机收到的和发出的所有的数据包:
tcpdump host 192.168.1.100
21、如果想要获取主机192.168.1.100除了和主机192.168.1.101之外所有主机通信的ip包,使用命令:
tcpdump ip host 192.168.1.100 and ! 192.168.1.101
22、如果想要获取主机 192.168.1.100 接收或发出的 telnet 包,使用如下命令:
tcpdump tcp port 23 host 192.168.1.100
#查看http请求的header
tcpdump -s 1024 -l -A -n host 192.168.9.56
tcpdump -s 1024 -l -A src 192.168.9.56 or dst 192.168.9.56
sudo tcpdump -A -s 1492 dst port 80
#本地网络中IP地址为192.168.0.5的主机现在与外界通信的情况
sudo tcpdump -i eth0 src host 192.168.0.5
#查看网卡eth0的http请求的tcp包
tcpdump -i eth0 port http
tcpdump -i eth0 port http or port smtp or port imap or port pop3 -l -A | egrep -i 'pass=|pwd=|log=|login=|user=|username=|pw=|passw=|passwd=|password=|pass:|user:|userna me:|password:|login:|pass |user '
#查看tcp,upd,icmp非ssh的包
tcpdump -n -v tcp or udp or icmp and not port 22
#查看http请求的request 包
sudo tcpdump -i eth0 port 80 -w -

#过滤http响应的get host头信息
sudo tcpdump -i en1 -n -s 0 -w - | grep -a -o -E "GET \/.*|Host\: .*"

#DNS查询请求响应包
sudo tcpdump -i en0 'udp port 53'

11. dig 命令

dig命令的全称是“domain information groper”,它是一个用来灵活查询DNS的工具,它会打印出DNS域名服务器的回应,dig命令主要用来从DNS域名服务器查询主机地址信息。

dig命令与nslookup命令功能基本相同,但是dig命令灵活性好、易用、输出清晰。

  • 常用参数
  • @:指定进行域名解析的域名服务器
  • -b:使用指定的本机ip地址向域名服务器发送域名查询请求
  • -x:执行逆向域名查询
  • -t: 指定要查询的DNS数据类型(默认为A)
  • -p:指定域名服务器所使用端口号
  • -4:使用ipv4(默认)
    -6:使用ipv6
  • -h: 显示命令帮助信息
查询对应域名的ip:
[root@rivers ~]# dig www.baidu.com

对目标ip进行反向解析查询:
[root@rivers ~]# dig -x 114.114.114.114

查询目标域名的MX记录:
[root@rivers ~]# dig -t MX www.baidu.com

## 12.iftop 命令

> - iftop是一款实时流量监控工具,监控TCP/IP连接等,缺点就是无报表功能。
> - 必须以root身份才能运行。
> - 常用参数:
> - -i 指定要监控的网卡
> - -n 直接显示IP, 不进行DNS反解析

默认监控第一块网卡的流量:
[root@rivers ~]# iftop

监控ens33网卡的流量:
[root@rivers ~]# iftop -i ens33

直接显示IP, 不进行DNS反解析:
[root@rivers ~]# iftop -n

13. nload 命令

  • nload默认会分页展示各个网卡的实时流量信息。我们可以通过按键盘上的 ← → 或者 Enter/Tab 键在网卡之间切换。
  • 常用参数:
  • -a 全部数据的刷新时间周期,单位是秒,默认是300s
  • -i 进入网卡的流量图的显示比例最大值设置,默认10240 kBit/s
  • -m 不显示流量图,只显示统计数据
  • -o 出去网卡的流量图的显示比例最大值设置,默认10240 kBit/s
  • -t 显示数据的刷新时间间隔,单位是毫秒,默认500ms
  • -u 设置右边Curr、Avg、Min、Max的数据单位,默认是h自动变的.注意大小写单位不同!
Bit(比特)是存储单元;Byte(字节)是计量单位,查看网络时常用Byte

nload -u h 自动变更单位,Bit/s
[root@rivers ~]#  nload -m -H ens33

nload -u H 自动变更单位,Byte/s

nload -m 不显示流量图 

nload -m -H ens33 不显示流量图,以Byte为单位查看ens33网卡流量情况

nload -t 显示数据的刷新时间间隔,单位是毫秒,设置为1000ms

14. nmap 命令

  • nmap (“Network Mapper(网络映射器)”) 是一款开放源代码的 网络探测和安全审核的工具。
  • 它的设计目标是快速地扫描大型网络,当然用它扫描单个 主机也没有问题。
  • Nmap以新颖的方式使用原始IP报文来发现网络上有哪些主机,那些主机提供什么服务(应用程序名和版本),那些服务运行在什么操作系统(包括版本信息), 它们使用什么类型的报文过滤器/防火墙,以及一堆其它功能。虽然Nmap通常用于安全审核, 许多系统管理员和网络管理员也用它来做一些日常的工作,比如查看整个网络的信息,管理服务升级计划,以及监视主机和服务的运行。
  • Nmap还能提供关于目标机的进一步信息,包括反向域名,操作系统猜测,设备类型,和MAC地址。
  • 常用参数:
  • –traceroute 扫描主机端口并跟踪路由
  • -p 扫描指定端口和端口范围
  • -p 使用高级功能进行扫描
  • -sP 对目标主机进行ping扫描
  • -sV 探测服务版本信息
root@rivers ~]# nmap -p 4430 www.baidu.com
-bash: nmap: command not found
[root@rivers ~]# yum -y provides nmap
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * base: mirrors.aliyun.com
 * extras: mirrors.aliyun.com
 * updates: mirrors.aliyun.com
2:nmap-6.40-19.el7.x86_64 : Network exploration tool and security
                          : scanner
Repo        : base

扫描主机并跟踪路由:
[root@rivers ~]# nmap --traceroute www.baidu.com

Starting Nmap 6.40 ( http://nmap.org ) at 2022-11-16 06:18 CST
Stats: 0:00:42 elapsed; 0 hosts completed (1 up), 1 undergoing SYN Stealth Scan

使用-p参数探测80、443端口:
[root@rivers ~]# nmap -p80,443 www.baidu.com
探测服务器的1-10000端口范围:
[root@rivers ~]# nmap -p1,10000 www.baidu.com

使用-A参数进行高级扫描:
[root@rivers ~]# nmap -A www.baidu.com

15.uptime 命令

  • uptime命令可以显示系统已经运行了多长时间,信息显示依次为:现在时间、系统已经运行了多长时间、目前有多少登录用户、系统在过去的1分钟、5分钟和15分钟内的平均负载。 uptime命令用法十分简单,直接输入uptime即可查看系统负载情况。
  • 常用参数:
  • -p 以漂亮的格式显示机器正常运行的时间
  • -s 系统自开始运行时间,格式为yyyy-mm-dd hh:mm:ss
  • -h 显示帮助信息
以漂亮的格式显示机器正常运行的时间
[root@rivers ~]# uptime -p   
up 2 days, 4 hours, 36 minutes
显示帮助信息
[root@rivers ~]# uptime -h

Usage:
 uptime [options]

Options:
 -p, --pretty   show uptime in pretty format
 -h, --help     display this help and exit
 -s, --since    system up since
 -V, --version  output version information and exit

For more details see uptime(1).
系统自开始运行时间
[root@rivers ~]# uptime -s
2022-11-15 01:33:07
[root@rivers ~]# uptime -p
up 2 days, 4 hours, 36 minutes

16. netstat 命令

  • netstat命令来自于英文词组”network statistics“的缩写,其功能是用于显示各种网络相关信息,例如网络连接状态、路由表信息、接口状态、NAT、多播成员等等。
  • netstat命令不仅应用于Linux系统,而且在Windows XP、Windows 7、Windows 10及Windows 11中均已默认支持,并且可用参数也相同,有经验的运维人员可以直接上手
  • 常用参数
-a 显示所有连线中的Socket
-p 显示正在使用Socket的程序识别码和程序名称
-l 仅列出在监听的服务状态
-t 显示TCP传输协议的连线状况
-u 显示UDP传输协议的连线状况
-i 网卡信息
-r 显示路由表信息
-n 直接使用IP地址,不通过域名服务器

显示系统网络状态中的所有连接信息:
root@rivers ~]# netstat -a
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp        0      0 0.0.0.0:ssh             0.0.0.0:*               LISTEN   
显示系统网络状态中的UDP连接信息:
[root@rivers ~]# netstat -nu
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
udp        0      0 172.19.226.238:68       172.19.239.253:67       ESTABLISHED    


显示系统网络状态中的UDP连接端口号使用信息:
[root@rivers ~]# netstat -apu
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address    Foreign Address       State    PID/Program name    
udp        0      0 linuxcool:bootpc _gateway:bootps  ESTABLISHED   1024/NetworkManager 
udp        0      0 localhost:323           0.0.0.0:*               875/chronyd      
显示网卡当前状态信息:
[root@rivers ~]# netstat -i 
Kernel Interface table
Iface             MTU    RX-OK RX-ERR RX-DRP RX-OVR    TX-OK TX-ERR TX-DRP TX-OVR Flg
ens33            1500    74054      0      0 0         34905      0      0      0 BMRU
lo              65536      851      0      0 0           851      0      0      0 LRU
显示网络路由表状态信息:

[root@rivers ~]# netstat -r
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
default         gateway         0.0.0.0         UG        0 0          0 ens33
192.168.10.0    0.0.0.0         255.255.255.0   U         0 0          0 ens33

找到某个服务所对应的连接信息

[root@rivers ~]# netstat -lantup|grep sshd
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      9388/sshd           
tcp        0     36 192.168.10.102:22       192.168.10.1:62844      ESTABLISHED 12028/sshd: root@pt 
tcp6       0      0 :::22                   :::*                    LISTEN      9388/sshd           

17.nmtui 命令

  • 通过nmtui提供的GUI界面,可以编辑连接,启动连接,设置主机名
  • 常用参数
Edit a connection      编辑连接

Activate a connection  激活连接

Set system hostname    设置主机名
```shell
# 查抄安装包
[root@rivers ~]# yum provides nmtui
Loaded plugins: fastestmirror
Determining fastest mirrors
 * base: mirrors.aliyun.com
 * extras: mirrors.aliyun.com
 * updates: mirrors.aliyun.com
updates/7/x86_64/filelists_db  |  10 MB     00:00     
1:NetworkManager-tui-1.18.8-1.el7.x86_64 :
     ...: NetworkManager curses-based UI
# 安装nmtui软件
yum install NetworkManager-tui 
# 进入图形界面
 nmtui

Edit a connection      编辑连接
Activate a connection  激活连接
Set system hostname    设置主机名
#修改完后需要手动重启相应的服务

# 重载网卡
[root@rivers ~]# nmcli connection reload ens33   
# 启动
[root@rivers ~]# nmcli con up ens33

19.nmcli 命令

  • nmcli命令来自于英文词组“NetworkManager command-line”的缩写,其功能是用于基于命令行配置网卡参数。nmcli与nmtui命令工具配置过的参数会直接写入到网卡服务配置文件中,永久生效。
  • Red Hat Enterprise Linux 7 与 CentOS 7 中默认的网络服务由 NetworkManager 提供,这是动态控制及配置网络的守护进程,它用于保持当前网络设备及连接处于工作状态,同时也支持传统的 ifcfg 类型的配置文件。
  • 常用参数
-c  监控和管理网络设备的连接
-d  监控和管理网络设备的接口 
12
  • nmcli 查看命令
 查看所有网络连接
[root@rivers ~]# nmcli connection show
NAME   UUID                                  TYPE      DEVICE 
ens33  c96bc909-188e-ec64-3a96-6a90982b08ad  ethernet  ens33  
[root@rivers ~]# 
查看活动的网络连接
[root@rivers ~]# nmcli connection show -active
NAME   UUID                                  TYPE      DEVICE 
ens33  c96bc909-188e-ec64-3a96-6a90982b08ad  ethernet  ens33  

查看网卡地址信息
[root@rivers ~]# nmcli device show ens33|grep "ADDRESS"
IP4.ADDRESS[1]:                         192.168.10.102/24
IP6.ADDRESS[1]:                         fe80::313d:5ec5:2360:b413/64

 查看指定网卡的详细信息
[root@rivers ~]# nmcli con show ens33
connection.id:                          ens33
connection.uuid:                        c96bc909-188e-ec64-3a96-6a90982b08
connection.stable-id:                   --
connection.type:                        802-3-ethernet
connection.interface-name:              ens33
connection.autoconnect:                 yes
显示指定网络设备的详细信息
[root@rivers ~]# nmcli device show
GENERAL.DEVICE:                         ens33
GENERAL.TYPE:                           ethernet
GENERAL.HWADDR:                         00:0C:29:1A:8B:6F
GENERAL.MTU:                            1500

  • 网络管理

    [root@rivers ~]# nmcli networking
    enabled
    [root@rivers ~]# nmcli networking help
    Usage: nmcli networking { COMMAND | help }
    
    COMMAND := { [ on | off | connectivity ] }
    
      on  
    
      off
    
      connectivity [check]
    
    [root@rivers ~]# nmcli networking on   # 启用网络
    [root@rivers ~]# nmcli networking off  # 关闭网络
    
    
  • nmcli 修改命令

# 启用网络连接
[root@rivers ~]# nmcli connection up ens33
Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/4)


# 停用网络连接(可以被自动激活)
[root@rivers ~]#nmcli con down ens33
# 禁用网卡,防止自动被激活
[root@rivers ~]#nmcli device disconnect ens33
# 删除网络连接的配置文件
[root@rivers ~]#nmcli con delete ens33
# 重新加载网络配置文件
[root@rivers ~]# nmcli connection reload ens33
[root@rivers ~]# 

  • 新增网卡配置文件
使用 add 命令会在 /etc/sysconfig/network-scripts中生成以为 ifcfg开头加add指定的 con-name 名称命名,此文件皆由 nmcli命令进行动态配置
  
# 如果手动修改 ifcfg文件,重启NetworkManager是无法生效,还需要在执行 nmcli con up才行
  
# 因此不建议手动修改配置文件,一切修改都使用nmcli命令,修改后执行 nmcli con up 立即生效
  
  # 动态获取IP方式的网络连接配置:
  nmcli con add con-name dynamic ifname ens36 type ethernet 
  #启用动态配置文件
  nmcli con up  dynamic
- 修改配置文件

  ```shell
  nmcli connection modify Con-Name [+|-]setting.propertyvalue
  
  setting.property:
  
  ipv4.method (manual | auto)
  ipv4.addresse
  ipv4.gateway
  ipv4.dns1
# 设置网卡自启动,实际修改的是网卡配置文件 ONBOOT=yes
nmcli con mod CON-NAME connection.autoconnect yes
# 修改IP地址是静态(manual)还是dhcp动态(auto)
# 实际修改的是网卡配置文件BOOTPROTO,BOOTPROTO=none 表示静态;BOOTPROTO=dhcp 表示动态
nmcli con mod CON-NAME ipv4.method manual(static) | auto
  # 修改IP配置及网关
  nmcli con mod CON-NAME ipv4.addresses “10.10.10.10/24 10.10.10.1”
  # 修改默认网关
  nmcli con mod CON-NAME ipv4.gateway 10.10.10.1
  # 添加第二个IP地址
  nmcli con mod CON-NAME +ipv4.addresses 10.10.10.10/16
  # 删除第二个IP地址
  nmcli con mod CON-NAME -ipv4.addresses 10.10.10.10/16
  # 添加dns1
  nmcli con mod CON-NAME ipv4.dns 114.114.114.114
  # 添加dns2
  nmcli con mod CON-NAME +ipv4.dns  8.8.8.8
  #修改配置文件
  nmcli con mod      			# ifcfg-* 文件
  # IP获取方式
  ipv4.method manual|static   # BOOTPROTO=none
  ipv4.method auto     		# BOOTPROTO=dhcp
  # 连接名称
  connection.id eth0     		# NAME=eth0
  #IP地址信息
  ipv4.addresses      
  “192.0.2.1/24      			# IPADDR0=192.0.2.1 PREFIX0=24
  192.0.2.254”      			# GATEWAY0=192.0.2.254
  # dns
  ipv4.dns 8.8.8.8     		# DNS0=8.8.8.8
  # dns搜索域
  ipv4.dns-search example.com  # DOMAIN=example.com
  
  ipv4.ignore-auto-dns true    # PEERDNS=no
  connection.autoconnect yes   # ONBOOT=yes
  connection.interface-name eth0  # DEVICE=eth0
  802-3-ethernet.mac-address... 	# HWADDR=...

20.ethtool命令

  • 显示某个网络适配器的驱动信息,适用于查询软件兼容性的情况
  • ethtool命令用于查询ethX网口基本设置、及设置网卡的参数
  • 常用参数
-i 显示网卡驱动的信息
-E 修改网卡只读存储器字节
-K 修改网卡 Offload 的状态
-s 修改网卡的部分配置
-t 让网卡执行自我检测

ethtool -i eth0
显示网络数据:
ethtool -S
设置适配器连接速度(Mbps)
ethtool speed <10|100|1000>
设置网口工作方式
ethtool -s eth0 autoneg off speed 100 duplex full 

总结

很多从机构刚出来的小伙伴在面试的时候被问到说出你常用的 20 个 linux 命令,通过命令的使用检验是否有实际工作经验。所以通过面试很容易发现问题。那么今天就分享几个运维、排障高效的几个 linux 命令。

以梦为马,不负韶华,流年笑掷,未来可期!
                     —黄昏

让生命像一团热烈燃烧的火,直到死亡才能使它熄灭


via:

  • linux shell 脚本 入门到实战详解 -CSDN博客 宝山的博客 已于 2023-01-01 21:57:19 修改

    <https://blog.csdn.net/weixin_42313749/article/details/120524768 >

  • 说出你常用的20个linux命令,你还是只会说ls、cat那20个命令吗?宝山的博客 已于 2022-11-17 23:11:07 修改

    https://blog.csdn.net/weixin_42313749/article/details/127913672


使用 shell 创建文本菜单和窗口部件

诗翔 发表于 2017-11-29

内容:

  • 创建文本菜单
  • 创建文本窗口部件
  • 添加X Window图形

创建文本菜单

创建交互式shell脚本最常用的方法是使用菜单,它提供了各种选项帮助脚本用户了解脚本能做到的和不能做的。

shell脚本菜单的核心是case命令,该命令会根据用户在菜单上的选择来执行特定命令。

下面逐步了解和创建基于菜单的shell脚本的步骤。

创建菜单布局

第一步是决定在菜单上显示哪些元素以及想要显示的布局方式。

在创建菜单前,通常先清空显示器上已有的内容。这样能在干净的,没有干扰的环境中显示菜单了。

clear命令使用当前终端的terminfo数据来清理出现在屏幕上的文字。运行clear命令后可以使用echo命令显示菜单元素。

**默认,echo命令只显示可打印的文本字符。**而在创建菜单时一些非文本字符也非常有用,比如制表符和换行符。需要添加-e选项使得echo命令能解析包含在其中的非文本字符。

例如,

wsx@wsx:~/tmp$ echo -e "1.\tDisplay disk space"
1.	Display disk space

这对于格式化菜单项布局非常方便,只需要几个echo命令就可以创建一个还不错的菜单。

clear
echo
echo -e "\t\t\tSys Admin Menu\n"
echo -e "\t1. Display disk space"
echo -e "\t2. Display logged on users"
echo -e "\t3. Display memory usage"
echo -e "\t0. Exit menu\n\n"
echo -en "\t\tEnter an option: "

最后一行-en选项去掉末尾换行符使得菜单更专业点,光标会在行尾等待用户输入。

创建菜单的最后一步是获取用户输入。 这一步用read命令。因为只期望用户使用单字符输入,在命令加-n选项进行限定。这样用户只需要输入一个数字,不用摁回车键。

read -n 1 option

创建菜单函数

shell 脚本菜单选项作为一组独立的函数实现起来更为容易。要做到这一点,要为每个菜单项创建独立的 shell 函数。第一步是决定希望脚本执行那些功能,然后将这些功能以函数的形式放在代码中。

通常会为还没有实现的函数先创建一个*桩函数*,它是一个控函数,或者只有一个echo语句,说明最终这里需要什么内容。

function diskspace {
    
    
  clear
  echo "This is where the diskspace commands will do"
}

这允许菜单在我实现某个函数时仍然能正常操作。不需要写出所有函数之后才能让菜单投入使用。函数从clear命令开始,这样就能在一个干净的屏幕上执行该函数,不会收到原先菜单的干扰。

另外,将菜单布局本身作为一个函数来创建有利于菜单制作。

function menu {
    
    
  	clear
	echo
	echo -e "\t\t\tSys Admin Menu\n"
	echo -e "\t1. Display disk space"
	echo -e "\t2. Display logged on users"
	echo -e "\t3. Display memory usage"
	echo -e "\t0. Exit menu\n\n"
	echo -en "\t\tEnter an option: "
	read -n 1 option
}

这样能在任何时候调用该函数以此重现菜单。

添加菜单逻辑

下一步需要创建程序逻辑将菜单布局和函数结合起来。这需要使用case命令。

case命令应该根据菜单中输入的字符来调用相应的函数,用case命令字符星号来处理所有不正确的菜单项。

下面展示了典型菜单的case用法:

menu
case $option in
0)
	break ;;
1)
	diskspace ;;
2)
	whoseon ;;
3)
	memusage ;;
*)
	clear
	echo "Sorry, wrong selection";;
esac

这里首先调用menu函数清空屏幕并显示菜单。menu函数中的read命令会一直等待,知道用户在键盘上键入一个字符。然后case命令会接管余下的处理过程,基于字符调用相应的函数。

整合shell脚本菜单

现在让将前面的步骤全部组合起来,看看它们是如何协作的。

这是一个完整的菜单脚本例子:

wsx@wsx:~/tmp$ cat test14
#!/bin/bash
# simple script menu

function diskspace {
    
    
	clear
	df -k
}

function whoseon {
    
    
	clear
	who
}

function memusage {
    
    
	clear
	cat /proc/meminfo
}

function menu {
    
    
	clear
	echo
	echo -e "\t\t\tSys Admin Menu\n"
	echo -e "\t1. Display disk space"
	echo -e "\t2. Display logged on users"
	echo -e "\t3. Display memory usage"
	echo -e "\t0. Exit menu\n\n"
	echo -en "\t\tEnter an option: "
	read -n 1 option
}

while [ 1 ]
do
	menu
	case $option in
	0)
		break ;;
	1)
		diskspace ;;
	2)
		whoseon ;;
	3)
		memusage ;;
	*)
		clear
		echo "Sorry, wrong selection" ;;
	esac
	echo -en "\n\n\t\t\tHit any key to continue"
	read -n 1 line
done
clear

使用:

			Sys Admin Menu

	1. Display disk space
	2. Display logged on users
	3. Display memory usage
	0. Exit menu


		Enter an option:

输入1:

文件系统           1K-块     已用      可用 已用% 挂载点
udev             4006080        0   4006080    0% /dev
tmpfs             807220    81004    726216   11% /run
/dev/sda4      305650672 14226064 275828680    5% /
tmpfs            4036100     1724   4034376    1% /dev/shm
tmpfs               5120        4      5116    1% /run/lock
tmpfs            4036100        0   4036100    0% /sys/fs/cgroup
/dev/sda3         524272     4684    519588    1% /boot/efi
tmpfs             807220       52    807168    1% /run/user/1000
tmpfs             807220       16    807204    1% /run/user/125
/dev/sda2      421886972 23340376 398546596    6% /media/wsx/存储


			Hit any key to continue

其他都可以自己测试一下,我就不赘言了。

使用select命令

select命令只需要一条命令就可以创建出菜单,然后获取输入的答案并自动处理。

命令格式如下:

select variable in list
do
	commands
done

list参数是由空格分隔的文本选项列表,这些列表构成了整个菜单。 select命令会将每个列表项显示成一个带编号的选项,然后为选项显示一个由PS3环境变量定义的特殊提示符。

wsx@wsx:~/tmp$ cat smenu1
#!/bin/bash
# using select in the menu

function diskspace {
    
    
	clear
	df -k
}

function whoseon {
    
    
	clear
	who
}

function memusage {
    
    
	clear
	cat /proc/meminfo
}

PS3="Enter an option: "
select option in "Display disk space" "Display logged on users" "Display memory usage" "Exit program"
do
	case $option in
	"Exit program")
		break ;;
	"Display disk space")
		diskspace ;;
	"Display logged on users")
		memusage ;;
	"Display memory usage")
		memusage ;;
	*)
		clear
		echo "Sorry, wrong selection";;
	esac
done
clear

运行会自动生成如下菜单项:

wsx@wsx:~/tmp$ ./smenu1
1) Display disk space	    3) Display memory usage
2) Display logged on users  4) Exit program
Enter an option:

在使用select命令时,存储在变量中的结果值是整个文本字符串而不是跟菜单项相关联的数字。文本字符串是要在case语句中比较的内容。

制作窗口

dialog包能够用ANSI转义控制字符在文本环境中创建标准的窗口对话框。可以将这些对话框融入自己的shell脚本中,借此与用户进行交互。这部分来学习如何使用dialog包。

安装:

sudo apt-get install dialog

dialog包

dialog包使用命令行参数来决定生成哪种窗口部件(widget)。部件是dialog包中窗口元素的术语。

部件 描述
calendar 提供选择日期的日历
checklist 显示多个选项(其中每个选项都能打开或关闭)
form 构建一个带有标签以及文本字段(可以填写内容)的表单
fselect 提供一个文件选择窗口来浏览选择文件
gauge 显示完成的百分比进度条
infobox 显示一条消息,但不用等待回应
inputbox 提供一个输入文本用的文本表单
inputmenu 提供一个可编辑的菜单
menu 显示可选择的一系列选项
msgbox 显示一条消息,并要求用户选择OK按钮
pause 显示一个进度条来显示暂定期间的状态
passwordbox 显示一个文本框,但会隐藏输入的文本
passwordform 显示一个带标签的隐藏文本字段的表单
radiolist 提供一组菜单选项,但只能选择其中一个
tailbox 用tail命令在滚动窗口中显示文件的内容
tailboxbg 跟tailbox一样,但是在后台模式中运行
textbox 在滚动窗口中显示文件的内容
timebox 提供一个选择小时、分钟和秒数的窗口
yesno 提供一条带有Yes和No按钮的简单消息

如上表所见,可以选择很多不同的部件。只需要多花点功夫就可以让脚本看起来更专业。

要在命令行上指定某个特定的部件,需要使用双破折线格式

dialog --widget parameters

其中widget是上表中某个特定的部件,parameters定义了部件窗口的大小以及部件需要的文本。

每个dialog部件都提供了两种形式的输出:

  • 使用STDERR
  • 使用退出状态码

可以通过dialog命令的退出状态码来确定用户选择的按钮。如果选择了Yes或OK按钮,命令会返回状态码0。如果选择了Cancer或No按钮,命令会返回状态码1。可用标准的$?变量来确定dialog部件具体选择了哪个按钮。

如果部件返回了数据,dialog命令会将数据发送到STDERR。可以用标准的bash shell方法将其重定向到另一个文件或文件描述符中。

dialog --inputbox "Enter your age:" 10 20 2>age.txt

这条命令将文本框输入的文本重定向到age.txt文本中。

msgbox部件

msgbox部件是对话框中最常见的类型。它会在窗口中显示一条简单的信息,直到用户点击OK后消失。

使用格式:

dialog --msgbox text height width

text参数是要在窗口显示的字符串,heightwidth参数设定自动换行的窗口大小。如果想要在窗口加一个标题,可以使用--title参数,后接作为标题的文本。

例子:

dialog --title Testing --msgbox "This is a test" 10 20

输入命令后,消息框会显示在终端上。如果终端仿真器支持鼠标,可以单击OK来关闭对话框,也可以按下回车键。

yesno部件

该部件在窗口底部生成两个按钮:一个是Yes,一个是No。用户可以用鼠标、制表符或者键盘方向键来切换按钮。选择按钮则使用空格或者回车键。

下面是一个例子:

wsx@wsx:~$ dialog --title "Please answer" --yesno "Is this thing on?" 10 20
# 中间终端有输出
wsx@wsx:~$ echo $?
0

dialog命令的退出状态码会根据用户选择的按钮来设置。选择No返回1,选择Yes就是0。

inputbox部件

inputbox 部件提供了一个简单的文本框区域来输入文本字符串,dialog 会将它传到 STDERR,需要重定向获得输入。inputbox 提供了两个按钮:OK 和 Cancel。如果选择了 OK,命令退出状态码为 0,否则为 1。

wsx@wsx:~/tmp$ dialog --inputbox "Enter your age:" 10 20 2>age.txt
wsx@wsx:~/tmp$ cat age.txt
24

如果自己运行过的话就会注意到该值后面没有换行符,这让能够轻松将文本内容重定向到脚本变量中,以获得用户输入的值。

textbox部件

textbox 部件是在窗口中显示大量信息的极佳办法。它会生成一个滚动窗口来显示由参数所指定的文件中的文本。

wsx@wsx:~/tmp$ dialog --textbox /etc/passwd 15 45

/etc/passwd文件内容显示在可滚动的文本窗口中,可以用方向键来左右或上下滚动显示文件的内容。窗口底部的行会显示当前查看文本处于文件中的哪个位置(百分比)。文本框只包含一个用来选择退出部件的Exit按钮。

menu部件

可以用这个部件来创建之前(上一篇笔记)中制作的文本菜单的窗口版本。只要为每个选项提供一个选择标号和文本就行。

wsx@wsx:~/tmp$ dialog --menu "Sys Admin Menu" 20 30 10 1 "Display disk space" 2 "Display users" 3 "Display memory usage" 4 "Exit" 2>test.txt

第一个参数定义了菜单的标题,之后的两个参数定义了菜单窗口的高和宽,而第四个参数则定义了在窗口中一次显示的菜单项总数。如果存在更多选择,则有滚动条。

菜单项必须使用菜单对:第一个元素是用来选择菜单项的标号(必须唯一);第二个元素是菜单中使用的文本。

dialog命令会将选定(鼠标点击或回车键或选择OK)的菜单项文本发送到STDERR。

fselect部件

该部件在处理文件名时非常方便。不用强制用户键入文件名,就可以用fselect部件来浏览文件的位置并选择文件。

使用格式:

wsx@wsx:~/tmp$ dialog --title "Select a file" --fselect $HOME/ 10 50 2>file.txt

第一个参数是窗口使用的其实目录位置。fselect部件窗口由左侧的目录列表、右侧的文件列表和含有当前选定的文件或目录的简单文本框组成。可以手动在文本框键入文件名,或者用目录和文件列表来选定(使用空格键选定)

dialog选项

除了标准部件,dialog 还有大量定制的选项。前面使用的title就是一个。

下面显示了命令可用的选项:

选项 描述
–add-widget 继续下一个对话框直到按下Esc或Cancel选项
–aspect ratio 直到窗口宽度和高度的宽高比
–backtitle title 直到显示在屏幕顶部背景上的图标
–begin x y 指定窗口左上角的起始位置
–cancel-label label 指定Cancel按钮的替代标签
–clear 用默认的对话背景色来清空屏幕内容
–colors 在对话文本中嵌入ANSI色彩编码
–cr-wrap 在对话文本中允许使用换行符并强制换行
–create-rc file 将示例配置文件的内容复制到指定的file文件中
–defaultno 将yes/no对话框的默认答案设为no
–default-item string 设定复选列表、表单或菜单对话中的默认项
–exit-label label 指定Exit按钮的替代标签
–extra-button 在OK按钮和Cancel按钮之间显示一个额外按钮
–extra-label label 指定额外按钮的替换标签
–help 显示dialog命令的帮助信息
–help-button 在OK按钮和Cancel按钮后显示一个Help按钮
–help-label label 指定Help按钮的替换标签
–help-status 当选定Help按钮后,在帮助信息后写入多选列表、单选列表或表单信息
–ignore 忽略dialog不能识别的选项
–input-fd fd 指定STDIN之外的另一个文件描述符
–insecure 在passwd部件中键入内容时显示星号
–item-help 为多选列表、单选列表或菜单中的每个标号在屏幕底部添加一个帮助栏
–keep-window 不要清除屏幕上显示过的部件
–max-input size 指定输入的最大字符串长度。默认为2048
–nocancel 隐藏Cancel按钮
–no-collapse 不要将对话文本中的制表符转换为空格
–no-kill 将tailboxbg对话放到后台,并禁止该进程的SIGHUP信号
–no-label label 为No按钮指定替换标签
–no-shadow 不要显示对话窗口的阴影效果
–ok-label label 指定OK按钮的替换标签
–output-fd fd 指定除STDERR之外的另一个输出文件描述符
–print-maxsize 将对话窗口的最大尺寸打印到输出中
–print-size 将每个对话窗口的大小打印到输出中
–print-version 将dialog的版本号打印到输出中
–separate-output 一次一行地输出checklist部件的结果,不使用引号
–separator string 指定用于分隔部件输出的字符串
–separate-widget string 指定用于分隔部件输出的字符串
–shadow 在每个窗口右下角绘制阴影
–single-quoted 需要时对多选列表的输出采用单引号
–sleep sec 在处理完对话窗口后延迟指定的秒数
–stderr 将输出发送到STDERR(默认)
–stdout 将输出发送到STDOUT
–tab-correct 将制表符转换为空格
–tab-len n 指定一个制表符占用的空格数(默认为8)
–timeout sec 指定无用户输入时,sec秒后退出并返回错误代码
–title title 指定对话窗口的标题
–trim 从对话文本中删除前导空格和换行符
–visit-tiems 修改对话窗口制表符的停留位置,使其包括选项列表
–yes-label label 为Yes按钮指定替换标签

**--backtitle选项是为脚本中的菜单创建公共标题的简便办法。**上表提供的强大特性允许创建任何需要的窗口。

dialog命令支持运行时配置。该命令会根据配置文件模板创建一份配置文件。dialog启动时会先去检查是否设置了DIALOGRC环境变量,该变量会保存配置文件名信息。如果未设置该变量或未找到该文件,它会将$HOME/.dialogrc作为配置文件。如果这个文件还不存在的话就尝试查找编译时指定的GLOBALRC文件,也就是/etc/dialogrc。如果还不存在就用编译时的默认值。

在脚本中使用dialog命令

必须记住两件事:

  • 如果有Cancel或No按钮,检查dialog命令的退出状态码
  • 重定向STDERR来获得输出值

接下来是一个简单的实例,使用dialog部件生成之前(上一篇笔记)所创建的系统管理菜单。

wsx@wsx-laptop:~$ cat menu3
#!/bin/bash
# using dialog to create a menu

temp=$(mktemp -t test.XXXXXX)
temp2=$(mktemp -t test2.XXXXXX)

function diskspace {
    
    
        df -k > $temp
        dialog --textbox $temp 20 60
}

function whoseon {
    
    
        who > $temp
        dialog --textbox $temp 20 50
}

function menusage {
    
    
        cat /proc/meminfo > $temp
        dialog --textbox $temp 20 50
}

while [ 1 ]
do
dialog --menu "Sys Admin Menu" 20 30 10 1 "Display disk space" 2 "Display users" 3 "Display memory usage" 0 "Exit" 2> $temp2
if [ $? -eq 1 ]
then
  break
fi

selection=$(cat $temp2)

case $selection in
1)
        diskspace ;;
2)
        whoseon ;;
3)
        memusage ;;
0)
        break ;;
*)
        dialog --msgbox "Sorry, invalid selection" 10 30
esac
done
rm -f $temp 2> /dev/null
rm -f $temp 2> /dev/null

使用 while 循环加一个真值常量创建了一个无限循环来显示菜单对话。当执行完每个函数后,脚本会返回继续显示菜单。

脚本使用了 mktemp 命令创建两个临时文件来保存 dialog 命令的数据。


猜你喜欢

转载自blog.csdn.net/u013669912/article/details/143277338