第一章、shell脚本基础
shell的作用:人和机器交互的工具--》其实是一个程序。shell里比较好用的程序是bash
默认情况下几乎所有的linux系统默认的shell都是bash
====
c语言为什么要编译。c语言是人认识的语言,根据某种编码进行翻译叫编译。
shell脚本编程的优势。
查看当前shell
[oracle@oracle ~]$ echo $SHELL/bin/bash[oracle@oracle ~]$
shell课程体系
Shell脚本编程 | |||
|
Shell基础 变量的使用 算术运算、数组应用 排序、提取、组合命令 |
条件测试 if语句、for循环、while循环、case分支和函数应用 |
正则表达式 expect dialog |
sed Awk 案例 |
第1-2章 |
第3-4章 |
第5-6章 |
第7-8章 |
知识要点
掌握Shell脚本的基础知识
学会使用Shell变量
学会编写简单的Shell脚本
shell脚本的运行环境
学习shell脚本的基本流程
看、想、写
shell脚本用在什么地方
编写常用系统维护工具菜单
重要的性能参数、进程和日志分析
自动实现数据备份计划
自动批量搭建特定系统环境
防火墙自动配置脚本
服务器的配置文件安全比对
对批量设备进行远程巡检
shell脚本的组成元素
shell脚本的基本组成
声明和注释
系统命令
文本处理工具(grep、cut、sed、awk…)
各种变量
各种条件判断
循环结构语句
各种函数
shell的作用
shell的作用---命令解释器,“翻译官”
介于系统内核与用户之间,负责解释命令行
shell脚本的优势
编译型语言
编写-编译-链接-运行(edit-compile-link-run)
C\C++、Ada、Java、C#
脚本语言
解释器读入脚本程序代码,将其转换成内部的形式执行
解释器本身则是编译型程序
Shell脚本编程的优势
语法和结构通常比较简单
学习和使用通常比较简单
通常以容易修改程序的“解释”作为运行方式,而不需要“编译”
登陆shell的种类和切换
登陆shell
指定用户每次登陆系统后自动加载的shell程序,大多数linux系统采用/bin/bash 作为默认登陆shell
/etc/shells 文件记录了系统支持的有效登陆shell。
[root@oracle ~]# cat /etc/shells/bin/sh ---》最小化安装都有/bin/bash ---》推荐使用/sbin/nologin/bin/dash/bin/tcsh/bin/csh/bin/ksh[root@oracle ~]#
如何切换shell环境
临时切换:直接执行其他shell程序,例如ksh、zsh等
返回到原来的shell环境时可以执行‘exit\'命令或者按ctrl+d快捷键
更改用户登陆shell:
需要修改/etc/passwd 文件中用户登陆的最后一个字段
或执行:usermod -s shell程序路径 用户名
shell初始化
bash初始化
登陆shell
指的是输入用户名、密码,从系统登陆时执行的第一个程序。
非登陆shell
登陆系统后,在login shell里启动的shell是非login shell
如执行bash命令、在图形中打开终端均是打开一个非登陆shell。
bash初始化
bash的启动脚本初始化
bash启动时,会进行初始化,初始化就是执行一些脚本。会执行哪些脚本分两种情况。
1、登陆时启动的bash,登陆shell
初始化脚本执行顺序:/etc/profile-->/etc/profile.d/*.sh-->~/.bash_profile-->~/.bashrc-->/etc/bashrc
如果这些脚本中的变量发出冲突,那么以最后一个脚本的设置生效。
2、登陆后,启动的bash,非登陆shell
初始化脚本执行顺序:~/.bashrc--->/etc/bashrc-->/etc/profile.d/*.sh
注意:这些脚本中不要乱增加内容。例如:在脚本中增加echo。
shell启动配置文件的区别
/etc/profile:配置全局环境变量,影响所有用户。
~/.bash_profile:配置个人环境,影响一个用户。
/etc/bashrc:配置全局的别名或者shell选项,影响所有用户。
~/.bashrc:配置个人别名或者shell选项,影响一个用户。
登陆和非登陆shell的区别
登陆shell负责系统全局环境初始化,会读取所有启动配置文件。
非登陆shell默认会继承登陆shell的环境变量,为了加快速度,无需读取所有启动配置文件,只需读取少量局部配置文件。
退出登陆shell:~/.bash_logout
env 查看环境变量set 查看当前用户可以使用的所有的变量
bash的命令历史
命令历史
保存用户曾经执行过的命令操作。
存放位置:~/.bash_history文件
查看命令历史
使用上箭头和下箭头 逐条翻看,允许编辑并重新执行
执行:history
清除历史命令
执行:history -c
查看命令历史
[root@oracle ~]# history1 cd /etc2 ls3 cd sysconfig4 ls5 cd network-scripts6 ls
调用名利历史
!n:执行历史命令中的第n条命令。
!str:执行历史记录中以str开头的命令
[root@oracle ~]# !2lsanaconda-ks.cfg Documents install.log Music Public tmpDesktop Downloads install.log.syslog Pictures Templates Videos[root@oracle ~]# !cdcd /backup[root@oracle backup]#
设置记录历史命令的条数
修改histsize参数(默认为1000条)
[root@oracle ~]# vi /etc/profile# /etc/profile# System wide environment and startup programs, for login setup# Functions and aliases go in /etc/bashrcHISTSIZE=1000
bash的命令别名
命令别名
为使用频率较高的复杂命令行设置简短的调用名称
存放位置:~/.bashrc
查看命令别名
格式:alias [别名]
设置命令别名
执行alias 别名=’实际执行的命令‘
取消已经设置的命令别名
格式:unalias 别名
unalias -a
查看命令别名
[root@oracle ~]# aliasalias cp=\'cp -i\'alias l.=\'ls -d .* --color=auto\'alias ll=\'ls -l --color=auto\'alias ls=\'ls --color=auto\'alias mv=\'mv -i\'alias rm=\'rm -i\'alias which=\'alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde\'[root@oracle ~]#
shell中命令的执行
无条件运行多个命令
cmd1;cmd2;cmd3
在子shell中执行命令
(cmd1;cmd2)
不影响父shell的环境
编写第一个shell脚本
编写脚本代码
使用vi文本编辑器
每行一条linux命令,按执行顺序依次编写
[root@localhost ~]# vi first.shcd /boot/pwdls -lh vml*
赋予可执行权限
使脚本具有可执行属性
[root@localhost ~]# chmod +x first.sh[root@localhost ~]# ls -l first.sh-rwxr-xr-x 1 root root 144 04-26 15:02 first.sh
执行脚本文件
第一种方法:脚本文件路径
第二种方法:bash 脚本文件路径
第三种方法:source或者. 脚本文件路径(使用.执行脚本,必须有执行权限)
更完善的脚本结构
1、脚本声明
2、注释信息
3、可执行语句
====声明:以#!开头注释:以#开头#!/bin/bash ---》申明使用bash作为默认shell来执行脚本##########################################Function: auto fdisk#Usage: bash auto_fdisk.sh#Author: Customer service department#Company: Alibaba Cloud Computing#Version: 2.0#########################################===========
注释:
1.给人看的
2.脚本不会执行
3.方便不熟悉的人,快速了解代码的作用
4.linux shell里以#开头的行是注释行
使用lftp命令下载文件和文件夹
[root@chinaitsoft lianxi]# lftp 172.16.1.1 登录ftp服务器
lftp 172.16.1.1:~> ls-rwxr-xr-x 1 0 0 17921378 Sep 09 18:19 PotPlayer视频播放器.zipdrwxr-xr-x 8 0 0 4096 Nov 20 19:10 linux-videodrwxr-xr-x 2 0 0 4096 Feb 29 13:46 mysqldrwxr-xr-x 4 0 0 4096 Sep 12 20:42 pythondrwxr-xr-x 7 0 0 4096 Mar 04 16:16 softwaredrwxr-xr-x 4 0 0 4096 Jan 23 15:10 teacher_fengdrwxr-xr-x 7 0 0 4096 Jan 05 13:44 videodrwxr-xr-x 2 0 0 4096 Dec 13 22:56 xianglftp 172.16.1.1:/> cd teacher_feng/lftp 172.16.1.1:/teacher_feng> lsdrwxr-xr-x 10 0 0 4096 Dec 21 15:16 9_classdrwxr-xr-x 10 0 0 4096 Mar 05 14:05 califeng-rw-r--r-- 1 0 0 13990 Oct 31 23:56 mysql_plan.xlsxlftp 172.16.1.1:/teacher_feng> cd 9_class/linux-shell-course/lftp 172.16.1.1:/teacher_feng/9_class/linux-shell-course> get yuli_admin_system_user-v2.sh6886 bytes transferredlftp 172.16.1.1:/teacher_feng/9_class/linux-shell-course>[root@chinaitsoft lianxi]# lftp 172.16.1.1lftp 172.16.1.1:~> bye[root@chinaitsoft lianxi]# lftp 172.16.1.1lftp 172.16.1.1:~> exit[root@chinaitsoft lianxi]# lftp 172.16.1.1lftp 172.16.1.1:~> quit[root@chinaitsoft lianxi]#====get是下载文件mirror 下载文件夹退出 quit bye exit默认情况下下载的文件或者文件夹存放在当前目录lftp 172.16.1.1:/> !ls 在本机上执行ls命令aa frist.sh sed yuli_admin_system_user-v2.shlftp 172.16.1.1:/>lftp 172.16.1.1:/> !pwd/lianxilftp 172.16.1.1:/> lcd /root 切换本地路径 locallcd 成功, 本地目录=/rootlftp 172.16.1.1:/>====
shell变量的作用、类型
变量的作用
为灵活管理linux系统提供特定参数了,有两层意思:
变量名:使用固定的名称,有系统预设或者用户定义
变量值:能够根据用户设置、系统环境变量的变化而变化。
变量的类型
自定义变量:由用户自己定义、修改和使用。
环境变量:由系统维护,用于设置工作环境。
位置变量:通过命令行给脚本程序传递参数。
预定义变量:bash中内置的一类变量,不能直接修改。
按变量使用的范围。
局部变量:只在当前的shell中有效。
全局变量:子shell会从父shell中继承变量。
自定义变量
定义新的变量
变量名要求以英文字母或下划线开头,不能以数字开头,区分大小写,约定俗称为大写(IP_addr),但是不强制。
等号两边不要空格。
格式:变量名=变量值
查看变量的值
格式:echo $变量名
[root@oracle ~]# day=sunday[root@oracle ~]# echo $daysunday[root@oracle ~]# DAY=sun[root@oracle ~]# echo $daysunday[root@oracle ~]# echo $DAYsun[root@oracle ~]#
通过$符号引用指定名称的变量值
变量值有空格用双引号括起来。
[root@oracle ~]# name="hai lian tian"[root@oracle ~]# echo $namehai lian tian[root@oracle ~]#
如果变量名容易和后面的字符和下划线连在一起导致混淆,则应该使用大括号将变量括起来${变量名}
[root@oracle ~]# DAY=Sunday[root@oracle ~]# echo "Today is Sunday" >$DAY_file.txt[root@oracle ~]# ls -a.txt[root@oracle tmp]# echo "today is sunday " >${DAY}_file.txt[root@oracle tmp]# ls -a. .. .esd-0 .ICE-unix Sunday_file.txt .X0-lock .X11-unix[root@oracle tmp]#
可以将命令的执行结果直接赋值给变量
var2=$(rpm -qf $(which fdisk))[root@oracle tmp]# var2=$(rpm -qf $(which fdisk))[root@oracle tmp]# echo $var2util-linux-ng-2.17.2-12.14.el6.x86_64[root@oracle tmp]#
readonly可以将变量设置为只读,变量一旦设置为只读,任何用户不能对此变量进行重新赋值。
variable=value #先对一个变量进行赋值
readonly variable #将variable设置为只读
利用unset命令可以清除变量的值
格式:unsettling 变量名
shell命令行替换
bash shell在解释命令前替换某些命令行元字符
通配符替换:* 、? 、[a-z]
历史命令替换:!! 、!n 、 !str
代字号替换: ~ 、~用户名
变量替换:$变量名 、${变量名}
大括号替换:{a,b,c}file、{aa,bb}/{aa,bb}
算数替换:+、-、*、/
{a,b,c}file afile/bfile/cfile
{aa,bb}/{aa,bb} aa/bb aa/aa bb/aa bb/bb
shell中引号
引用和转义字符
使用特殊字符时,就是表示本身,不使用其特殊意义
\:避免下一个字符被shell解释
双引号 " " :避免双引号内除了$、! 和 `(反引号)以外的其他字符被shell解释。
单引号 ’ ’ :避免单引号内的任何字符被shell解释
反引号 `` :命令替换,提取命令执行后的输出结果 和$()相同
单引号、双引号、反引号的区别。
shell替换发生在命令运行之前。
实验案例1
编写脚本显示如下图所示效果,分析显示的结果。
name="hello"
myname0=\'My name is $name\'
myname1="My name is \'$name\'"
myname2=\'My name is "$name"\'
myname3="My $name is "$name"" #就近配对 my hello is hello
myname4=\'My $name is \'$name\'\' #就近配对 my $name is hello
echo $myname0
echo $myname1
echo $myname2
echo $myname3
echo $myname4
[root@oracle tmp]# name="hello"[root@oracle tmp]# myname0=\'My name is $name\'[root@oracle tmp]# myname1="My name is \'$name\'"[root@oracle tmp]# myname2=\'My name is "$name"\'[root@oracle tmp]# myname3="My name is "$name""[root@oracle tmp]# myname4=\'My name is \'$name\'\'[root@oracle tmp]# echo $myname0My name is $name[root@oracle tmp]# echo $myname1My name is \'hello\'[root@oracle tmp]# echo $myname2My name is "$name"[root@oracle tmp]# echo $myname3My name is hello[root@oracle tmp]# echo $myname4My name is hello[root@oracle tmp]#
echo命令
echo命令的-e选项表示将转义符\后跟字符形成的特殊字符解释成特殊意义。
| 符号 | 意义 |
| \n | 新的一行 |
| \t | 表示tab键 |
[root@oracle ~]# echo -e "\tabc123"abc123[root@oracle ~]# echo -e "\tabc\n123"abc123[root@oracle ~]#
从键盘输入内容为变量赋值
格式:read [选项] 变量名
选项
-p:提示信息
-s:隐藏输入(密码时用)
-t:指定超时时间
-n:指定读取的长度 //密码结束 //y/n //按任意键结束。
[root@db11g touch1]# read -s -p "please input passwd:" passwd
please input passwd:
[root@oracle tmp]# cat read.sh#!/bin/bash###############################Function: read using#Us#Author: wangyu#Company: haitianjingyu#Version: 1.0##############################read -p "please input you name:" nameread -n3 -s -p "input password:" pwdecho -e "\n you username is $name ,password is $pwd"[root@oracle tmp]# bash read.shplease input you name:haiinput password:you username is hai ,password is hai[root@oracle tmp]#
[root@db11g touch1]# echo -n "please:" && read var1
please:
-n:表示不换行。
实验案例2
编写脚本显示如下图所示效果,要求选择一个菜单后,不用按回车马上显示结果
脚本代码:
[root@oracle tmp]# vi menu.sh
#!/bin/bash###############################Function: menu#Author: wangyu#Company: haitianjingyu#Version: 1.0##############################clearecho -e "\n\t\t\t***system menager tool***"echo -e "\n\t1.\tshow disk space info"echo -e "\t2.\tshow network connector info"echo -e "\t3.\tshow memory using info"echo -e "\t0.\texit menu"echo -en "\n\t\tinput option:"read -n1 numecho -e "\nyou option is $num"
运行效果:
实验案例3
编写脚本,根据输入的用户名和密码(密码不显示出来)自动新建用户并配置密码,脚本运行如下图所示(不能显示多余的提示)
脚本如下
[root@oracle tmp]# cat adduser.sh#!/bin/bash###########################Function: create new user#Author: wangyu#Company: haitianjingyu#Version: 1.0##########################read -p "add new user:" nameread -s -p "user $name password:" pwduseradd $nameecho $pass|passwd --stdin $name &>/dev/nullecho -e "\nuser $name is ok"[root@oracle tmp]# bash adduser.shadd new user:hai2user hai2 password:user hai2 is ok[root@oracle tmp]#
自定义变量
设置变量的作用范围
格式1: export 变量名...
格式2:export 变量名=变量值...
-----两种格式可以混合使用
export 查看全局变量
全局变量
查看全局变量
set命令可以查看所有的shell变量,其中包括全局变量。
env命令只查看全局变量。
环境变量
由系统提前创建,用来设置用户的工作环境。
配置文件:/etc/profile、~/.bash_profile
常见的环境变量:
pwd、path
user、logname、uid、ppid、shell、home
ps1、$ps2
位置变量
表示为$n ,n为1~9之间的数字。
大于9的位置参数要用{},例如${10}.
实验4编写脚本实现统计目录数目。
预定义变量
$#:命令中位置变量的个数
$*:所有变量的内容(不常用)
$@:所有变量的内容
$0:当前执行的进程名
$$:当前shell的pid
$?:上一条命令的执行返回状态,当返回状态值为0时,表示执行正常,非0时表示执行异常或者出错。
$RANDOM:随机数,可以作为临时文件名。
touch abc$RANDOM.txt
有条件运行多个命令
备份脚本的使用
bash的重定向操作
改变标准输入、标准输出、标准错误输出的方向。
程序名和进程名可能不同。
正确输出可以重定向到不同的文件。
创建oracle 表空间
#!/bin/bash
read -p "请输入表空间的名字:" name
sqlplus / as sysdba<<eof
CREATE BIGFILE TABLESPACE ${name}
DATAFILE \'${name}.dbf\'
SIZE 20M AUTOEXTEND ON;
eof >> /dev/null
echo "成功!"
统计文件夹下后缀名。
#!/bin/bash
read -p "请输入查找的文件夹: " DIR
for i in "$@"
do
if(i!=0){
NUM=$(find $DIR -type f -name "*$i" | wc -l)
echo "以$i结尾的文件的数目是: " $NUM
}
fi
done
yum 的安装
#!/bin/bash
read -p "请输入一个挂载点的目录绝对路径:" DIR
mkdir -p $DIR
umount /dev/sr0 &> /dev/null
mount /dev/sr0 $DIR &> /dev/null
(cd /etc/yum.repos.d; tar *.repo *repo.tar &> /dev/null)
cat << EOF > /etc/yum.repos.d/yumlocal.repo
[Server]
name=Server
baseurl=file:///$DIR
enabled=1
gpgcheck=0
EOF
yum clean all &> /dev/null && echo yum is ok