shell的作用:人和机器交互的工具--》其实是一个程序。
shell里比较好用的程序是bash
默认情况下几乎所有的linux系统默认的shell都是bash
====
c语言为什么要编译。c语言是人认识的语言,根据某种编码进行翻译叫编译。
shell脚本编程的优势。
查看当前shell
[[email protected] ~]$ echo $SHELL
/bin/bash
[[email protected] ~]$
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。
[[email protected] ~]# cat /etc/shells
/bin/sh ---》最小化安装都有
/bin/bash ---》推荐使用
/sbin/nologin
/bin/dash
/bin/tcsh
/bin/csh
/bin/ksh
[[email protected] ~]#
如何切换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
查看命令历史
[[email protected] ~]# history
1 cd /etc
2 ls
3 cd sysconfig
4 ls
5 cd network-scripts
6 ls
调用名利历史
!n:执行历史命令中的第n条命令。
!str:执行历史记录中以str开头的命令
[[email protected] ~]# !2
ls
anaconda-ks.cfg Documents install.log Music Public tmp
Desktop Downloads install.log.syslog Pictures Templates Videos
[[email protected] ~]# !cd
cd /backup
[[email protected] backup]#
设置记录历史命令的条数
修改histsize参数(默认为1000条)
[[email protected] ~]# vi /etc/profile
# /etc/profile
# System wide environment and startup programs, for login setup
# Functions and aliases go in /etc/bashrc
HISTSIZE=1000
bash的命令别名
命令别名
为使用频率较高的复杂命令行设置简短的调用名称
存放位置:~/.bashrc
查看命令别名
格式:alias [别名]
设置命令别名
执行alias 别名=’实际执行的命令‘
取消已经设置的命令别名
格式:unalias 别名
unalias -a
查看命令别名
[[email protected] ~]# alias
alias 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‘
[[email protected] ~]#
shell中命令的执行
无条件运行多个命令
cmd1;cmd2;cmd3
在子shell中执行命令
(cmd1;cmd2)
不影响父shell的环境
编写第一个shell脚本
编写脚本代码
使用vi文本编辑器
每行一条linux命令,按执行顺序依次编写
[[email protected] ~]# vi first.sh
cd /boot/
pwd
ls -lh vml*
赋予可执行权限
使脚本具有可执行属性
[[email protected] ~]# chmod +x first.sh
[[email protected] ~]# 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命令下载文件和文件夹
[[email protected] 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视频播放器.zip
drwxr-xr-x 8 0 0 4096 Nov 20 19:10 linux-video
drwxr-xr-x 2 0 0 4096 Feb 29 13:46 mysql
drwxr-xr-x 4 0 0 4096 Sep 12 20:42 python
drwxr-xr-x 7 0 0 4096 Mar 04 16:16 software
drwxr-xr-x 4 0 0 4096 Jan 23 15:10 teacher_feng
drwxr-xr-x 7 0 0 4096 Jan 05 13:44 video
drwxr-xr-x 2 0 0 4096 Dec 13 22:56 xiang
lftp 172.16.1.1:/> cd teacher_feng/
lftp 172.16.1.1:/teacher_feng> ls
drwxr-xr-x 10 0 0 4096 Dec 21 15:16 9_class
drwxr-xr-x 10 0 0 4096 Mar 05 14:05 califeng
-rw-r--r-- 1 0 0 13990 Oct 31 23:56 mysql_plan.xlsx
lftp 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.sh
6886 bytes transferred
lftp 172.16.1.1:/teacher_feng/9_class/linux-shell-course>
[[email protected] lianxi]# lftp 172.16.1.1
lftp 172.16.1.1:~> bye
[[email protected] lianxi]# lftp 172.16.1.1
lftp 172.16.1.1:~> exit
[[email protected] lianxi]# lftp 172.16.1.1
lftp 172.16.1.1:~> quit
[[email protected] lianxi]#
====
get是下载文件
mirror 下载文件夹
退出 quit bye exit
默认情况下下载的文件或者文件夹存放在当前目录
lftp 172.16.1.1:/> !ls 在本机上执行ls命令
aa frist.sh sed yuli_admin_system_user-v2.sh
lftp 172.16.1.1:/>
lftp 172.16.1.1:/> !pwd
/lianxi
lftp 172.16.1.1:/> lcd /root 切换本地路径 local
lcd 成功, 本地目录=/root
lftp 172.16.1.1:/>
====
shell变量的作用、类型
变量的作用
为灵活管理linux系统提供特定参数了,有两层意思:
变量名:使用固定的名称,有系统预设或者用户定义
变量值:能够根据用户设置、系统环境变量的变化而变化。
变量的类型
自定义变量:由用户自己定义、修改和使用。
环境变量:由系统维护,用于设置工作环境。
位置变量:通过命令行给脚本程序传递参数。
预定义变量:bash中内置的一类变量,不能直接修改。
按变量使用的范围。
局部变量:只在当前的shell中有效。
全局变量:子shell会从父shell中继承变量。
自定义变量
定义新的变量
变量名要求以英文字母或下划线开头,不能以数字开头,区分大小写,约定俗称为大写(IP_addr),但是不强制。
等号两边不要空格。
格式:变量名=变量值
查看变量的值
格式:echo $变量名
[[email protected] ~]# day=sunday
[[email protected] ~]# echo $day
sunday
[[email protected] ~]# DAY=sun
[[email protected] ~]# echo $day
sunday
[[email protected] ~]# echo $DAY
sun
[[email protected] ~]#
通过$符号引用指定名称的变量值
变量值有空格用双引号括起来。
[[email protected] ~]# name="hai lian tian"
[[email protected] ~]# echo $name
hai lian tian
[[email protected] ~]#
如果变量名容易和后面的字符和下划线连在一起导致混淆,则应该使用大括号将变量括起来${变量名}
[[email protected] ~]# DAY=Sunday
[[email protected] ~]# echo "Today is Sunday" >$DAY_file.txt
[[email protected] ~]# ls -a
.txt
[[email protected] tmp]# echo "today is sunday " >${DAY}_file.txt
[[email protected] tmp]# ls -a
. .. .esd-0 .ICE-unix Sunday_file.txt .X0-lock .X11-unix
[[email protected] tmp]#
可以将命令的执行结果直接赋值给变量
var2=$(rpm -qf $(which fdisk))
[[email protected] tmp]# var2=$(rpm -qf $(which fdisk))
[[email protected] tmp]# echo $var2
util-linux-ng-2.17.2-12.14.el6.x86_64
[[email protected] 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
[[email protected] tmp]# name="hello"
[[email protected] tmp]# myname0=‘My name is $name‘
[[email protected] tmp]# myname1="My name is ‘$name‘"
[[email protected] tmp]# myname2=‘My name is "$name"‘
[[email protected] tmp]# myname3="My name is "$name""
[[email protected] tmp]# myname4=‘My name is ‘$name‘‘
[[email protected] tmp]# echo $myname0
My name is $name
[[email protected] tmp]# echo $myname1
My name is ‘hello‘
[[email protected] tmp]# echo $myname2
My name is "$name"
[[email protected] tmp]# echo $myname3
My name is hello
[[email protected] tmp]# echo $myname4
My name is hello
[[email protected] tmp]#
echo命令
echo命令的-e选项表示将转义符\后跟字符形成的特殊字符解释成特殊意义。
符号 | 意义 |
\n | 新的一行 |
\t | 表示tab键 |
[[email protected] ~]# echo -e "\tabc123"
abc123
[[email protected] ~]# echo -e "\tabc\n123"
abc
123
[[email protected] ~]#
自定义变量
从键盘输入内容为变量赋值
格式:read [选项] 变量名
选项
-p:提示信息
-s:隐藏输入(密码时用)
-t:指定超时时间
-n:指定读取的长度 //密码结束 //y/n //按任意键结束。
[[email protected] touch1]# read -s -p "please input passwd:" passwd
please input passwd:
[[email protected] tmp]# cat read.sh
#!/bin/bash
##############################
#Function: read using
#Us
#Author: wangyu
#Company: haitianjingyu
#Version: 1.0
##############################
read -p "please input you name:" name
read -n3 -s -p "input password:" pwd
echo -e "\n you username is $name ,password is $pwd"
[[email protected] tmp]# bash read.sh
please input you name:hai
input password:
you username is hai ,password is hai
[[email protected] tmp]#
[[email protected] touch1]# echo -n "please:" && read var1
please:
-n:表示不换行。
实验案例2
编写脚本显示如下图所示效果,要求选择一个菜单后,不用按回车马上显示结果
脚本代码:
[[email protected] tmp]# vi menu.sh
#!/bin/bash
##############################
#Function: menu
#Author: wangyu
#Company: haitianjingyu
#Version: 1.0
##############################
clear
echo -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 num
echo -e "\nyou option is $num"
运行效果:
实验案例3
编写脚本,根据输入的用户名和密码(密码不显示出来)自动新建用户并配置密码,脚本运行如下图所示(不能显示多余的提示)
脚本如下
[[email protected] tmp]# cat adduser.sh
#!/bin/bash
##########################
#Function: create new user
#Author: wangyu
#Company: haitianjingyu
#Version: 1.0
##########################
read -p "add new user:" name
read -s -p "user $name password:" pwd
useradd $name
echo $pass|passwd --stdin $name &>/dev/null
echo -e "\nuser $name is ok"
[[email protected] tmp]# bash adduser.sh
add new user:hai2
user hai2 password:
user hai2 is ok
[[email protected] 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编写脚本实现统计目录数目。
预定义变量
$#:命令中位置变量的个数
$*:所有变量的内容(不常用)
[email protected]:所有变量的内容
$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
"[email protected]"
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