本文最后更新于 2024-11-15,文章内容可能已经过时。

shell 脚本概念

🎈shell 和 shell 脚本有什么区别

确切一点说,Shell 就是一个命令行解释器,它的作用就是遵循一定的语法将输入的命令加以解释并传给系统。

🎈shell 环境介绍

如果是不带有图形环境的 Linux 系统(比如专用于服务器的系统),启动后就直接是命令行环境。不过,现在大部分的 Linux 发行版,尤其是针对普通用户的发行版,都是图形环境。用户登录系统后,自动进入图形环境,需要自己启动终端模拟器,才能进入命令行环境。

所谓「终端模拟器」(terminal emulator)就是一个模拟命令行窗口的程序,让用户在一个窗口中使用命令行环境,并且提供各种附加功能,比如调整颜色、字体大小、行距等等。不同 Linux 发行版(准确地说是不同的桌面环境)带有的终端程序是不一样的,比如 KDE 桌面环境的终端程序是 konsole,Gnome 桌面环境的终端程序是 gnome-terminal,用户也可以安装第三方的终端程序。所有终端程序,尽管名字不同,基本功能都是一样的,就是让用户可以进入命令行环境,使用 Shell。

🎈shell 脚本基本格式

shell 脚本 --- .sh

#! --- 约定标记,告诉这个脚本使用哪个命令解释器来执行

- 增加 可执行 x 权限

/bin/bash --- 若执行过程中,出现命令执行失败,则会继续执行接下来的命令

/bin/sh --- 若执行过程中,出现命令执行失败,则会停止执行接下来的命令

没有约定标记 --- 默认是 /bin/bash --- 是对应着用户的 默认命令解释器

案例 1:脚本修改静态 IP

#! /bin/bash
cd /etc/sysconfig/network-scripts/
echo "
TYPE=Ethernet
BOOTPROTO=static
DEFROUTE=yes
NAME=ens33
DEVICE=ens33
ONBOOT=yes
IPADDR=192.168.61.177
NETMASK=255.255.255.0
GATEWAY=192.168.61.254
DNS1=114.114.114.114
DNS2=218.85.157.99
" > ifcfg-ens33
systemctl restart network
ifconfig ens33

🎈shell 变量

变量名和等号之间不能有空格,这可能和你熟悉的所有编程语言都不一样。同时,变量名的命名须遵循如下规则:

1. 命名只能使用英文字母,数字和下划线,首个字符不能以数字开头。

2. 中间不能有空格,可以使用下划线「_」。

3. 不能使用标点符号。

4. 不能使用 bash 里的关键字(可用 help 命令查看保留关键字)。

A=demo --- echo $A

🎈read 交互

read 简介

要与 Linux 交互,脚本获取键盘输入的结果是必不可少的。

选项:

  • -n:限制读取 N 个字符就自动结束读取,如果没有读满 N 个字符就按下回车或遇到换行符,则也会结束读取。

  • -N:严格要求读满 N 个字符才自动结束读取,即使中途按下了回车或遇到了换行符也不结束。换行符或回车算一个字符。

  • -p:给出提示符。默认不支持 "\n" 换行,要换行需要特殊处理,见下文示例。例如,"-p 请输入密码:"

  • -r:禁止反斜线的转义功能。这意味着 "\" 会变成文本的一部分。

  • -s:静默模式。输入的内容不会回显在屏幕上。

#! /bin/bash
read -p "请输入IP地址: " IP
read -p "请输入网关地址: " GATE
cd /etc/sysconfig/network-scripts/
echo "
TYPE=Ethernet
BOOTPROTO=static
DEFROUTE=yes
NAME=ens33
DEVICE=ens33
ONBOOT=yes
IPADDR=$IP
NETMASK=255.255.255.0
GATEWAY=$GATE
DNS1=114.114.114.114
DNS2=218.85.157.99
" > ifcfg-ens33
systemctl restart network
ifconfig ens33

🎈定时任务

#! /bin/bash
cd /etc/sysconfig/network-scripts/
echo "
TYPE=Ethernet
BOOTPROTO=static
DEFROUTE=yes
NAME=ens33
DEVICE=ens33
ONBOOT=yes
IPADDR=192.168.61.177
NETMASK=255.255.255.0
GATEWAY=192.168.61.254
DNS1=114.114.114.114
DNS2=218.85.157.99
" > ifcfg-ens33
ifdown ens33
ifup ens33
ifconfig ens33

🎈crond

systemctl status crond.service  //查看定时任务服务的状态
yum -y install cronie  //下载安装定时服务
rpm -q cronie  //查看服务的版本
crontab -u //设定某个用户的cron服务
crontab -l //查看crontab任务
crontab -r //删除crontab定时任务

vim /etc/crontab // 定时任务配置文件

* 9,15 * * * root /home/zyl/Desktop/network.sh 

每天的上午 9 点和下午 15 点 root 执行脚本

crontab /etc/crontab  //重新加载
/var/log/cron  //定时任务的日志

案例 2:存活主机探测

ping -c2 -i0.5 -w1 192.168.61.1

参数:

  • -c 发包数

  • -i 发包的间隔

  • -w 等待时间

🎈特殊文件

/dev/null:在类 Unix 系统中,/dev/null,或称空设备,是一个特殊的设备文件,它丢弃一切写入其中的数据(但报告写入操作成功),读取它则会立即得到一个 EOF。在程序员行话,尤其是 Unix 行话中,/dev/null 被称为位桶 (bit bucket) 或者黑洞(black hole)。空设备通常被用于丢弃不需要的输出流,或作为用于输入流的空文件。这些操作通常由重定向完成。

/dev/zero:在类 UNIX 操作系统中, /dev/zero 是一个特殊的文件,当你读它的时候,它会提供无限的空字符 (NULL, ASCII NUL, 0x00)。其中的一个典型用法是用它提供的字符流来覆盖信息,另一个常见用法是产生一个特定大小的空白文件。BSD 就是通过 mmap 把 /dev/zero 映射到虚地址空间实现共享内存的。可以使用 mmap 将 /dev/zero 映射到一个虚拟的内存空间,这个操作的效果等同于使用一段匿名的内存(没有和任何文件相关)

🎈if 判断语句

if 条件
then 成立 语句
else 不成立 语句
fi

条件代码

  • -gt(greater than) 大于

  • -lt(less than) 小于

  • -eq(equal) 等于

  • -ne(not equal) 不等于

  • -le(less than or equal) 小于等于

  • -ge(greater than or equal)大于等于

示例

#! /bin/bash
if [ 10 -gt 20 ]
then
 echo "yes"
else
 echo "no"
fi

示例 2

#! /bin/bash
if ping -c2 -i0.5 -w1 192.168.61.1 > /dev/null
then
 echo "up"
else
 echo "down"
fi
echo $?  ---  判断返回值

🎈三种文本流

0:标准输入

1:标准输出

2:标准错误

🎈循环语句

💡for 循环

for 变量 in 取值列表
do
子语句
done

例子

#! /bin/bash
for IP in {1..254}
do
 if ping -c2 -i0.5 -w1 192.168.61.$IP > /dev/null
 then
  echo "192.168.61.$IP is up"
 else
  echo "192.168.61.$IP is down"
 fi
done

💡while 循环

while 条件
do
子语句
done

例子

#! /bin/bash
IP=0
while [ $IP -le 254 ]
do
 let IP++
 if ping -c2 -i0.5 -w1 192.168.61.$IP > /dev/null
 then
  echo "192.168.61.$IP is up"
 else
  echo "192.168.61.$IP is down"
 fi
done

🎈case 选择语句

case 变量 in
模式1)
子语句
;;
模式2)
子语句
;;
子语句
esac

例子

#! /bin/bash
read -p "input i : " i
case $i in 
1)
echo zyx
;;
2)
echo llw
;;
3)
echo crj
;;
*)
echo nobody
esac
./case.sh 1  2  3
    |     |  |  |
    $0    $1 $2 $3