day12_shell编程与运维

一、Shell 脚本概述

通过 Shell 中的各种命令, 开发者和运维人员可以对服务器进行维护工作。

但每次都手动输入命令, 工作效率太低, 而且很容易出错, 尤其是需要维护大量服务器时。

为了能够对服务器批量执行操作, 我们可以将需要执行的命令写入文件, 批量执行, 这种文件便是 Shell 脚本。

Shell 脚本一般是以 .sh 结尾的文本文件, 当然, 也可以省略扩展名。

二、Shell 脚本首行

脚本文件第一行通过注释的方式指明执行脚本的程序。

在 Shell 脚本中, # 开头的文本是注释, 但第一句 #! 开头的这句话比较特殊, 他会告诉 Shell 应该使用哪个程序来执行当前脚本。

常见方式有:

  • #!/bin/sh
  • #!/bin/bash
  • #!/usr/bin/env bash

Python 脚本的第一句一般是 #!/usr/bin/env python

三、第一个脚本

  1. 创建 cpu-count.sh 文件

  2. 将下面文本写入 cpu-count.sh 中

     #!/bin/bash
    
     echo "Hello"
     echo "I am `whoami`"
     echo "I love Linux"
     echo "The CPU in my PC has `cat /proc/cpuinfo |grep -c processor` cores"
     exit 0
    

执行 chmod a+x cpu-count.sh 对脚本授予可执行权限

输入 ./cpu-count.sh 执行脚本

查看脚本的退出状态: echo $?

  • Linux 中的所有程序执行结束后都有状态码
  • 状态码为 表示正常, 状态码为 正整数 代表异常退出

四、变量

  1. 定义

    变量的定义与其他语言差距不大, 需要注意的是赋值前后没有空格。

  # 变量定义: 等号前后没有空格
  a=12345
  b=xyz
  1. 使用

使用变量时, 变量名前面加上 $

 echo "---$a---\n===$b==="
 printf "---$a---\n===$b===\n"
  1. 注意 引号 的差别
 echo "---$a---\n===$b==="
 echo '---$a---\n===$b==='
  • 定义当前Shell下的全局变量

    • 定义: export ABC=9876543210123456789

    • 定义完后, 在终端里用 source 加载脚本: source ./test.sh

  • 常用的系统环境变量

    • $PATH: 可执行文件目录
    • $PWD: 当前目录
    • $HOME: 家目录
    • $USER: 当前用户名
    • $UID: 当前用户的 uid

五、获取用户输入

read -p "请输入一个数字:" num
echo "您输入的是:$num"

六、脚本里的引号

在shell里支持三种引号,它们的使用场景以及效果会有差异。

  • 反引号:里面的内容会被解析成为脚本
 echo `ls -a /home/chris`   # 打印 /home/chris目录下的所有文件和文件夹
  • 双引号:它里面的大部分内容会别原样显示,但是如果是一个变量,这个变量会被解析。
name=zhangsan
echo "大家好,我是$name"  # 大家好,我是zhangsan
  • 单引号:它里面的内容会完全原样输出,就算是有变量,也不会被解析。
name=zhangsan
echo '大家好,我是$name'  # 大家好,我是$name

七、脚本里的$

  1. ${var}用来获取一个变量的值,一般情况下,大括号可以省略不写。
name=zhangsan
echo ${name}  # zhangsan
echo $name  # zhangsan
  1. 特殊变量
$# 代表传入参数的个数
$@ 代表传入参数的列表
$0 代表脚本本身
$1 代表传入的第一个参数,$2$3...以此类推
$* 以字符串方式显示所有传入的参数
$$ 脚本运行的进程ID
$? 显示最后命令的退出状况,0表示没有错误
  • $(cmd)用来执行括号里的脚本命令,相当于使用反引号。
	echo $(ls /home/wubantu/Desktop)  # 列出当前用户的桌面上的所有文件和文件夹
  • $((expression))用来计算数学表达式expression的值。
echo $((1+1))  # 2
  • 例子:
   1 #!/bin/bash
   2 read -p "请输入一个字符串:" str
   3 echo "您输入的字符串是:"$str
   4
   5 name=zhangsan
   6
   7 echo "您的名字是:"$name
   8 echo "传入参数的个数是:"$#      
   9 echo "传入参数的列表是:"$@      
  10 echo "传入脚本本身是:"$0        
  11 echo "传入的第一个参数是:"$1
  12 echo "脚本运行的进程ID是:"$$
  13 echo "显示最后命令的退出状况是:"$?
  14
  15 echo "列出用户桌面上所有文件夹和文件"$(ls /home/wubantu/Desktop)
  16
  17 echo "1+1的值是:"$((1+1))
  
  # 结果是:
 
 请输入一个字符串:hello
 您输入的字符串是:hello
 您的名字是:zhangsan
 传入参数的个数是:0
 传入参数的列表是:
 传入脚本本身是:bash
 传入的第一个参数是:
 脚本运行的进程ID是:6054
 显示最后命令的退出状况是:0
 列出用户桌面上所有文件夹和文件
 1+1的值是:2

八、分支语句: if

分支控制语句完整格式为:

if command;then
    commands
elif command;then
    commands
else
    commands
fi
  1. if 语句检查判断的依据实际上是, 后面所跟的命令的状态码: 0 为 true, 其他值 为 false
 if ls /xxx;then
     echo 'exist xxx'
 else
     echo 'not exist xxx'
 fi
  1. 条件测试命令: [ ... ]
  • shell 提供了一种专用做条件测试的语句 [ ... ]

  • 这一对方括号本质上是一个命令, 里面的条件是其参数, 所以 [ 的后面和 ] 的前面必须有空格, 否则会报错。

  • 他可以进行三种比较

    • 数值比较
    • 字符串比较
    • 文件比较
  • 用法:

   if [ condition ];then
       commands
   fi

3.条件列表

  • 数值比较

    Condition 说明
    n1 -eq n2 检查n1是否与n2相等
    n1 -ge n2 检查n1是否大于或等于n2
    n1 -gt n2 检查n1是否大于n2
    n1 -le n2 检查n1是否小于n2
    n1 -lt n2 检查n1是否小于n2
    n1 -ne n2 检查n1是否不等于n2
  • 字符串比较

    Condition 说明
    str1 = str2 检查str1是否和str2相同(注意:等号两边要加空格)
    str1!=str2 检查str1是否和str2不同
    str1 检查str1是否小于str2(需要使用[[]])
    str1>str2 检查str1是否大于str2(需要使用[[]])
    -n str1 检查str1的长度是否非0(变量需要添加双引号)
    -z str1 检查str1的长度是否为0
  • 文件比较

    Condition 说明
    -d file 检查file是否存在并且是一个目录
    -e file 检查file是否存在
    -f file 检查file是否存在并且是一个文件
    -r file 检查file是否存在并且可读
    -w file 检查file是否存在并且可写
    -x file 检查file是否存在并且可执行
    -s file 检查file是否存在并且非空
    -O file 检查file是否存在并且属于当前用户所有
    -G file 检查file是否存在并且所属组与当前用户相同
    file1 -nt file2 检查file1是否比file2新
    file1 -ot file2 检查file1是否比file2旧

九、case语句

case  "$var" in
         exp1)
         command1
         ;;
         exp2)
         command2
         ;;
         exp3)
         command3
         ;;
         *)
         comman4
         ;;
esac

例子:

#!/bin/bash
read -p "请输入数字:" num
case $num in
    0)
        echo 星期日
        ;;
    1)
        echo 星期一
        ;;
    2)
        echo 星期二
        ;;
    3)
        echo 星期三
        ;;
    4)
        echo 星期四
        ;;
    5)
        echo 星期五
        ;;
    6)
        echo 星期六
        ;;
    *)
        echo 其他
        ;;
esac

# 结果
请输入数字:2
星期二

十、循环语句: for

  1. for循环的基本格式
for 变量 in 序列
do
	要执行的命令
done
  1. 例子:打印1到10中的偶数
 for i in `seq 1 10`
 do
     if [ $[ $i % 2] == 0 ]
     then
         echo "偶数: $i"
     else
         echo "奇数: $i"
     fi
 done


结果:
奇数: 1
偶数: 2
奇数: 3
偶数: 4
奇数: 5
偶数: 6
奇数: 7
偶数: 8
奇数: 9
偶数: 10

  • seq START END 语句用来产生一个数字序列
  • $[ NUM1 + NUM2 ] 语句用来进行基本的数学运算
  • [[ ... ]] 语句用来更方便的进行比较判断
  1. C语言风格的 for 循环
 for ((i=0; i<10; i++))
 do
     echo "num is $i"
 done
 
 
 结果:
num is 0
num is 1
num is 2
num is 3
num is 4
num is 5
num is 6
num is 7
num is 8
num is 9

十一、函数

  1. 函数定义

    定义时 function 不是必须的,可以省略

   function foo() {
       echo "---------------------------"
       echo "Hello $1, nice to meet you!"
       echo "---------------------------"
   }
  1. 函数的使用
  • 在终端或脚本中直接输入函数名即可,不需要小括号

  • 传参也只需将参数加到函数名后面,以空格做间隔,像正常使用命令那样

 foo arg1 arg2 arg3 ...
  1. 例子
 bar() {
     echo "执行者是 $0"
     echo "参数数量是 $#"
     echo "全部的参数 $@"
     echo "全部的参数 $*"

     if [ -d $1 ]; then  # 检查传入的第一个参数是否是文件夹
         for f in `ls $1`
         do
             echo $f
         done
     elif [ -f $1 ]; then
         echo "This is a file: $1"  # 如果不是文件夹, 直接显示文件名
     else
         echo 'not valid'  # 前面都不匹配显示默认语句
     fi
 }
 bar $1


结果:
执行者是 bash
参数数量是 0
全部的参数
全部的参数
01-体验.sh
02-引号的使用.sh
03-变量的使用.sh
04-$符号的使用.sh
05-if语句的使用.sh
06-case语句
07-for语句.sh
08-C语言风格.sh
09-函数的参数.sh
hello.py
ppp
sss
test.sh
ttt

十二、数组

数组中可以存放多个值。Bash Shell 只支持一维数组(不支持多维数组),初始化时不需要定义数组大小。

与大部分编程语言类似,数组元素的下标由0开始

  • 定义数组:

Shell 数组用括号来表示,元素用"空格"符号分割开,语法格式如下:

array_name=(value1 ... valuen)

同时,也可以直接使用下标来定义一个数组。

nums[0]=1
nums[1]="good"
nums[2]=yes
  • 获取和修改数组数据

使用下标可以直接修改数组里的数据。

arr=(hello good "yes" a 12)
arr[0] = hi

使用$和下标可以获取一个数组里的数据,但是注意需要使用{}来包裹变量。

语法格式:

${arr[index]}

示例:

arr=(hello good "yes" a 12)
echo ${arr[0]}
  • 获取数组所有数据以及长度

使用*或者@作为下标,可以获取数组里的所有数据。

arr=(hello good "yes" a 12)
echo ${arr[*]}
echo ${arr[@]}

结果:
hello good yes a 12
hello good yes a 12

在获取所有数据的前面添加# 可以获取到数组的长度

arr=(hello good "yes" a 12)
echo ${#arr[*]}
echo ${#arr[@]}

结果:
5
5
  • 数组的遍历

    • 使用for循环遍历
 #!/bin/bash
 arr=(hello good 12 'yes' hi)
 for((i=0;i)
 
 结果:
 bash: 11-遍历数组.sh: line 4: syntax error: unexpected end of file
  • 使用for…in遍历
#!/bin/bash
arr=(hello good 12 'yes' hi)
for ele in ${arr[*]}
do
    echo $ele
done

结果:
hello
good
12
yes
hi

你可能感兴趣的:(python自学之路)