Shell 脚本应用(一)
一、Shell 基础
1.为什么用 Shell 脚本
2.用户的登录 Shell
二、重定向与管道操作
1.重定向操作
2.管道符操作
三、使用 Shell 变量
1.自定义变量
2.变量赋值的特殊操作
四、特殊的 Shell 变量
1.环境变量
2.位置变量
3.预定义变量
一、Shell 基础
1.为什么用 Shell 脚本
用来解决服务器自动化运维,减轻管理员的工作量,解决大量的重复性的输入和交互式操作问题。
2.用户的登录 Shell
- Shell:一个特殊的应用程序,位于用户和操作系统内核之间,用来把用户输入的命令解释给系统内核去执行,并输出执行结果 (解释器)
- 查看 Linux 系统所支持的 Shell 脚本种类:cat /etc/shells
[root@localhost ~]# cat /etc/shells /bin/sh /bin/bash # /bin/bash 是大多数 Linux 系统的默认 Shell /usr/bin/sh /usr/bin/bash /bin/tcsh /bin/csh
1)编写一个 Shell 脚本
基本格式:
[root@localhost ~]# vim shell.sh # 前面的 shell 可以随意. 后缀必须为 .sh #!/bin/bash # 脚本声明 # This is a Simple Shell Script # 注释 cd /mnt # 脚本要执行的命令 echo "当前目录位于:" pwd
2)执行脚本
- ./ 方式必须加可执行权限。
[root@localhost ~]# chmod +x 1.sh [root@localhost ~]# ./1.sh
- sh 方式不需要加执行权限。
[root@localhost ~]# sh 1.sh
二、重定向与管道操作
1.重定向操作
1)重定向输入
- <:从指定的文件读取数据,而不是从键盘输入。
[root@localhost ~]# vim passwd.txt ABC123, [root@localhost ~]# useradd zhangsan [root@localhost ~]# passwd --stdin zhangsan < passwd.txt 更改用户 zhangsan 的密码 。 passwd:所有的身份验证令牌已经成功更新。
2)重定向输出
- >:将输出结果保存到指定的文件(覆盖原文件)。
[root@localhost ~]# uname -p > a.txt [root@localhost ~]# cat a.txt x86_64
- >>:将输出结果追加到指定的文件。
[root@localhost ~]# uname -r >> a.txt [root@localhost ~]# cat a.txt x86_64 3.10.0-1062.el7.x86_64 #这是追加进来的
3)错误重定向输出
- 2>:将错误信息保存到指定的文件(覆盖原文件)。
[root@localhost ~]# tar jcf /nonedir/etc.tgz /etc/ 2> error.log [root@localhost ~]# cat error.log tar: 从成员名中删除开头的“/” tar (child): /nonedir/etc.tgz:无法 open: 没有那个文件或目录 tar (child): Error is not recoverable: exiting now
- 2>>:将错误信息追加到指定的文件中。
[root@localhost ~]# cdd 2>> error.log [root@localhost ~]# cat error.log tar: 从成员名中删除开头的“/” tar (child): /nonedir/etc.tgz:无法 open: 没有那个文件或目录 tar (child): Error is not recoverable: exiting now bash: cdd: 未找到命令... 相似命令是: 'cd'
4)混合输出
- &>:表示直接把正确的输出和错误的输出都直接保存到后面的文件中,后面文件的原始数据丢失。
[root@localhost ~]# pwd &> a.sh [root@localhost ~]# cat a.sh /root
- &>>:表示直接把正确的输出和错误的输出都直接追加到后面的文件中,原始文件数据保留。
[root@localhost ~]# pwdd &>> a.sh [root@localhost ~]# cat a.sh /root bash: pwdd: 未找到命令... 相似命令是: 'pwd'
2.管道符操作
- 管道符:将管道符号 | 左侧命令的操作结果,作为右侧命令的执行对象。(同一行命令中可以使用多个)
[root@localhost ~]# grep "/bin/bash$" /etc/passwd root:x:0:0:root:/root:/bin/bash admin:x:1000:1000:admin:/home/admin:/bin/bash zhangsan:x:1002:1002::/home/zhangsan:/bin/bash [root@localhost ~]# grep "/bin/bash$" /etc/passwd | wc -l 3
三、使用 Shell 变量
Shell 变量是用来存放系统和用户需要使用的特定参数,这些特定参数会根据用户的设定或环境的变化而变化,Shell 变量的使用能够提供更强的适应性与功能。
1.自定义变量
- 由系统用户自己去定义,只在用户自己的 Shell 环境中有效,又称为本地变量。
- 基本格式:变量名=变量值(其中"="是赋值符号,变量名需要以字母或者下划线开头,不能包含特殊字符)
[root@localhost ~]# xm=zhangsan #定义变量xm,并赋值为zhangsan [root@localhost ~]# nl=18 #定义变量nl,并赋值为18 [root@localhost ~]# echo $xm #查看变量xm zhangsan [root@localhost ~]# echo $aaa #查看变量aaa,因为没有定义aaa,所以结果为空 [root@localhost ~]# echo $xm nl #每一个不同变量,都需要再前面加上一个"$"符号 zhangsan nl [root@localhost ~]# echo $xm $nl #查看变量xm与变量nl zhangsan 18
2.变量赋值的特殊操作
1)双引号的使用场合
- a:当赋值内容中包含空格时必须使用双引号。
[root@localhost ~]# PYTHON=Python 2.7.14 #错误赋值 bash: 2.7.14: 未找到命令... [root@localhost ~]# PYTHON="Python 2.7.14" #正确赋值 [root@localhost ~]# echo $PYTHON Python 2.7.14
- b:当赋值内容中用 $ 引用了其它变量时,必须要使用双引号。
[root@localhost ~]# aaa="ni hao" #赋值 aaa 值 [root@localhost ~]# echo $aaa ni hao [root@localhost ~]# bbb="$aaa ma" #将 aaa 值赋予给 bbb [root@localhost ~]# echo $bbb ni hao ma
2)单引号的使用场合
- 当赋值内容中包含 $ 、双引号、\ 等含有特殊的字符时,需要使用单引号扩起来。
[root@localhost ~]# aaa='ni hao $b' #单引号不会引用其他变量 [root@localhost ~]# echo $aaa ni hao $b
3)反撇号的使用
- 用于命令的替换或者是命令的赋值;把某个命令的执行结果赋值给变量。
[root@localhost ~]# shijian=`date` #把 date 这个命令的执行结果赋值给 shijian [root@localhost ~]# echo $shijian #查询 2020年 09月 04日 星期五 17:47:48 CST #返回的时间
4)read 命令
- 用来提示用户从键盘读入数据,赋值给变量。从而实现简单的交互过程。
[root@localhost ~]# read aaa #普通赋值 ni hao wo shi zhangsan [root@localhost ~]# echo $aaa ni hao wo shi zhangsan [root@localhost ~]# read -p "你是谁" bbb #设置提示信息,以便告知用户输入说明内容 (使交互操作更加友好,提高易用性) 你是谁wo shi zhangsan [root@localhost ~]# echo $bbb wo shi zhangsan
5)变量的使用范围
- 局部变量:只在当前 Shell 环境中有效。
- 全局变量:在所有 Shell 环境中有效。
[root@localhost ~]# boss=aaa #定义局部变量 [root@localhost ~]# export boss #把局部变量转化为全局变量 [root@localhost ~]# echo $boss aaa [root@localhost ~]# bash #进入子Shell [root@localhost ~]# echo $boss #再次进行查看,可以正常显示 aaa [root@localhost ~]# export aaa=zhangsan #直接将变量设置全局变量 [root@localhost ~]# echo $aaa zhangsan
6)变量的运算
[root@localhost ~]# X=100 [root@localhost ~]# echo $X 100 [root@localhost ~]# Y=20 [root@localhost ~]# echo $Y 20 [root@localhost ~]# expr $X - $Y #减法运算: - 80 [root@localhost ~]# expr $X \* $Y #乘法运算: \* 2000 [root@localhost ~]# expr $X / $Y #除法运算: / 5 [root@localhost ~]# expr $X % $Y #求模(取余)运算: % 0
四、特殊的 Shell 变量
1.环境变量
- 由系统提前创建,用来设置用户的工作环境。
配置文件: /etc/profile ~/.bash_profile
[root@localhost ~]# env #查看当前环境变量
常见的环境变量:
- USER:表示用户名称。
- HOME:表示用户的宿主目录。
- LANG:表示语言个字符集。
- PWD:表示当前所在工作目录。
- PATH:表示命令搜索路径。
[root@localhost ~]# echo $HOSTNAME = hostname #查看主机名 [root@localhost ~]# echo $PWD = pwd #查看当前的工作目录 [root@localhost ~]# echo $LANG #查看语言个字符集 [root@localhost ~]# echo $PATH #查看默认的搜索路径
改变环境变量:
- 临时更改: 给搜索路径中添加 /root 执行 PATH="$PATH:/root" 会立即生效,重启后失效。
[root@localhost ~]# ll aaa.sh #查看脚本文件的位置 -rwxr-xr-x 1 root root 54 9月 4 18:32 aaa.sh [root@localhost ~]# chmod +x aaa.sh #赋予aaa.sh可执行权限 [root@localhost ~]# PATH="$PATH:/root" #立即生效,重启后消失 [root@localhost ~]# aaa.sh #可以直接以文件名运行脚本 当前目录位于: /boot
- 永久更改: 给搜索路径中永久添加 root: 执行。
[root@localhost ~]# echo PATH="$PATH:/root" >> /etc/profile #把搜索路径添加到环境变量的主配置文件 [root@localhost ~]# . /etc/profile #立即执行脚本,让环境变量立即生效
2.位置变量
使用 Shell 脚本程序时,方便通过目录行为程序提供操作参数(也叫位置参数;使用$1、$2、… $9 表示;$1 表示脚本或命令后的第一个位置,然后依次类推)
[root@localhost ~]# vim qh.sh #!/bin/bash SUM=`expr $1 + $2` #定义变量SUM,SUM的值是位置变量 1 和位置变量 2 的和 echo "$1 + $2 = $SUM" #返回值的含义就是 $1 + $2 = $1 + $2 [root@localhost ~]# chmod +x qh.sh #赋予脚本可执行权限 [root@localhost ~]# ./qh.sh 100 11 #100就是$1;11就是$2 100 + 11 = 111 #返回的结果
- 注意:如果当位置变量超过 $9,即 $10,$11 … 时,则需要使用 { } 来括起来。如: ${11}
3.预定义变量
- 由 bash 程序预先定义好的一类特殊变量,用户只能使用,不能创建和修改预定义变量。
预定义变量:
- $#:命令行中位置变量的个数。
- $*:所有位置变量的内容。(在 for 循环中如果 $* 用 " " 括起来的情况下,则会把位置变量视为整体来输出。如:$1 $2 … $n 的形式输出所有参数)
- $@:所有位置变量的内容。(在 for 循环中如果 $@ 用 " " 括起来的情况下,则会把位置视为个体来输出。如:$1、$2、… $n 的形式输出所有参数)
- $0:当前执行的进程/程序名。
- $$:Shell 脚本本身的 PID 号(ProcessID,即脚本运行的当前进程 ID 号)
- $!:后台运行的最后一个进程的 PID 号。
- $?:上一条命令执行后返回的状态,当返回状态值为 0 时表示执行正常,非 0 值表示执行异常或出错。
[root@localhost ~]# vim beifen.sh #!/bin/bash #这是一个备份脚本 A=beifen-$(date +%F).tgz #定义变量格式 /usr/bin/tar zcf $A $* &> /dev/null echo "执行 $0 脚本" echo "共对 $# 个进行备份" for B in "$*" do echo '$*的位置变量内容:'"$B" done for C in "$@" do echo '$@的位置变量内容:'"$C" done echo "当前脚本的进程号为:$$" [root@localhost ~]# bash beifen.sh /etc/passwd /etc/shadow [root@localhost ~]# echo $?