目录
一、shell基础
1、shell的作用
-
Linux 系统中的 Shell 脚本是一个特殊的应用程序,它介于操作系统内核与用户之间,充当了一个“命令解释器”的角色,负责接收用户输入的操作指令(命令)并进行解释,将需要执行的操作传递给内核执行,并输出执行结果。
-
常见的 Shell 解释器程序有很多种,使用不同的 Shell 脚本时,其内部指令、命令行提示等方面会存在一些区别。通过/etc/shells 文件可以了解当前系统所支持的 Shell 脚本种类。
#列出系统中所有的Shell [root@localhost ~]# cat /etc/shells/bin/sh/bin/bash/usr/bin/sh/usr/bin/bash
#查看当前环境变量$SHELL的值 [root@localhost ~]# echo $SHELL/bin/bash
2、Shell的类型
命令 | 作用 |
---|---|
Bourne Shell | 是贝尔实验室开发的,Unix普遍使用的Shell,在编程方面比较优秀,但在用户交互方面没有其他Shell优秀。 |
Korn Shell | 是对Bourne Shell 的发展,在大部分内容上与Bourne Shell兼容,集成了C Shell和Bourne shell优点。 |
BASH | 是GNU的Bourne Again Shell,是GNU操作系统上默认的Shell,在Bourne Shell基础上增强了很多特性,如命令补全,命令历史表 |
C Shell | 是SUN公司Shell的BSD版本,语法与c语言相似,比bourne shell 更适合编程 |
3、第一个shell脚本
-
新建shell文件
[root@localhost ~]# vim first.sh cd /boot pwd ls -lh vml*
-
s添加执行权限
[root@localhost ~]# chmod +x first.sh [root@localhost ~]# ls -ld first.sh -rwxr-xr-x. 1 root root 25 12月 26 23:46 first.sh
-
执行shell脚本(3种执行方式)
#使用 ./ 执行需要添加执行权限 [root@localhost ~]# ./first.sh /boot -rwxr-xr-x. 1 root root 6.5M 12月 20 04:36 vmlinuz-0-rescue-5255c7d84d8048d6b0bce26a490ad173 -rwxr-xr-x. 1 root root 6.5M 8月 8 2019 vmlinuz-3.10.0-1062.el7.x86_64
-
使用
sh
、.
、source
来执行就不需要添加执行权限
[root@localhost ~]# sh first.sh /boot -rwxr-xr-x. 1 root root 6.5M 12月 20 04:36 vmlinuz-0-rescue-5255c7d84d8048d6b0bce26a490ad173 -rwxr-xr-x. 1 root root 6.5M 8月 8 2019 vmlinuz-3.10.0-1062.el7.x86_64
#以下两种方式相等 [root@localhost ~]# . first.sh [root@localhost ~]# source first.sh/boot -rwxr-xr-x. 1 root root 6.5M 12月 20 04:36 vmlinuz-0-rescue-5255c7d84d8048d6b0bce26a490ad173 -rwxr-xr-x. 1 root root 6.5M 8月 8 2019 vmlinuz-3.10.0-1062.el7.x86_64
-
-
完善脚本(
#!/bin/bash
这是一个特殊声明,echo
用于输出字符串)[root@localhost ~]# vim first.sh #!/bin/bash # 这是我的第一个shell脚本。 cd /boot echo "当前的目录位于:" pwd echo "其中以 vml 开头的文件包括:" ls -lh vml* [root@localhost ~]# sh first.sh 当前的目录位于: /boot 其中以 vml 开头的文件包括: -rwxr-xr-x. 1 root root 6.5M 12月 20 04:36 vmlinuz-0-rescue-5255c7d84d8048d6b0bce26a490ad173 -rwxr-xr-x. 1 root root 6.5M 8月 8 2019 vmlinuz-3.10.0-1062.el7.x86_64
二、重定向与管道操作
1、重定向操作
-
标准输入(STDIN):默认的设备是键盘,文件编号为 0,命令将从标准输入文件中读取在执行过程中需要的输入数据,使用
<
操作符[root@localhost ~]# vim pass.txt 123456 [root@localhost ~]# passwd --stdin zhangsan < pass.txt #需要关闭seLinux 更改用户 zhangsan 的密码 。 passwd:所有的身份验证令牌已经成功更新。
-
标准输出(STDOUT):默认的设备是显示器,文件编号为 1,命令将执行后的输出结果发送到标准输出文件。
-
重定向输出使用
>
或>>
操作符号,分别用于覆盖或追加文件
[root@localhost ~]# uname -p > kernel.txt [root@localhost ~]# cat kernel.txt x86_64
[root@localhost ~]# uname -r >> kernel.txt [root@localhost ~]# cat kernel.txt x86_64 3.10.0-514.el7.x86_64
-
-
标准错误(STDERR):默认的设备是显示器,文件编号为 2,命令将执行期间的各种错误信息发送到标准错误文件。
-
错误重定向使用“2>”操作符,其中“2”是指错误文件的编号(在使用标准输出、标准输入重定向时,实际上省略了 1、0 编号)。
[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>
操作符时,会像使用>
操作符一样覆盖目标文件的内容,若要追加内容而不是覆盖文件,则应改用2>>
操作符
-
-
当命令输出的结果可能既包括标准输出(正常执行)信息,又包括错误输出信息时,可以使用操作符
>
2>
将两类输出信息分别保存到不同的文件,也可以使用&>
操作符将两类输出信息保存到同一个文件
类型 | 操作符 | 用途 |
---|---|---|
重定向输入 | < | 从指定的文件读取数据,而不是从键盘输入 |
重定向输出 | > >> | 将输出结果保存到指定的文件(覆盖原有内容) 将输出结果追加到指定的文件 |
标准错误输出 | 2> 2>> | 将错误信息保存到指定的文件(覆盖原有内容) 将错误信息追加到指定的文件中 |
混合输出 | &> | 将标准输出、标准错误的内容保存到同一个文件中 |
2、管道操作
-
管道(pipe)操作为不同命令之间的协同工作提供了一种机制,位于管道符号“|”左侧的命令输出的结果,将作为右侧命令的输入(处理对象),同一行命令中可以使用多个管道。
#过滤前 [root@localhost ~]# grep "/bin/bash$" /etc/passwd root:x:0:0:root:/root:/bin/bash zhangsan:x:1000:1000::/home/zhangsan:/bin/bash #使用 awk 做进一步过滤(-F指定分隔符,print打印字段1和字段7) [root@localhost ~]# grep "/bin/bash$" /etc/passwd | awk -F: '{print $1,$7}' root /bin/bash zhangsan /bin/bash
[root@localhost ~]# df -hT 文件系统 类型 容量 已用 可用 已用% 挂载点 devtmpfs devtmpfs 475M 0 475M 0% /dev tmpfs tmpfs 487M 0 487M 0% /dev/shm tmpfs tmpfs 487M 7.7M 479M 2% /run tmpfs tmpfs 487M 0 487M 0% /sys/fs/cgroup /dev/mapper/centos-root xfs 50G 1.4G 49G 3% / /dev/sda1 xfs 1014M 137M 878M 14% /boot /dev/mapper/centos-home xfs 47G 33M 47G 1% /home tmpfs tmpfs 98M 0 98M 0% /run/user/0 [root@localhost ~]# df -hT | grep "/$" | awk '{print $6}' 3%
3、实验操作
-
使用shell脚本编写一个自动编译安装httpd服务器的脚本
- 下载源码包 - 安装编译环境(gcc、gcc-c++、make) - 安装httpd依赖软件 - 解包 - 配置 - 编译 - 安装 - 修改配置文件(使用sed命令 sed -i '3i ServerName 192.168.1.1:80' httpd.conf 直接修改原文件在第三行插入内容) - 启动服务器
三、shell变量
1、自定义变量
-
由用户自己定义、修改和使用
变量名=变量值echo $变量名
[root@localhost ~]# school=woniuxy [root@localhost ~]# echo $school woniuxy
-
使用
{}
括号[root@localhost ~]# classes=wangan [root@localhost ~]# echo $classes7.5 .5 [root@localhost ~]# echo ${classes}7.5 wangan7.5
-
赋值时使用引号
-
双引号
" "
(允许通过$符号引用其他变量值,变量值中出现空格时使用)[root@localhost ~]# classes="wangan 7.5" [root@localhost ~]# echo $classes wangan 7.5
[root@localhost ~]# classes=wangan [root@localhost ~]# version=7.5 [root@localhost ~]# wnwa="$classes $version" [root@localhost ~]# echo $wnwa wangan 7.5
-
单引号
' '
(禁止引用其他变量值,$视为普通字符)[root@localhost ~]# wnwa='$classes $version' [root@localhost ~]# echo $wnwa $classes $version
-
反撇号
``
,当出现嵌套命令替换时改用$()
(命令替换,提取命令执行后的输出结果)[root@localhost ~]# ls -lh `which useradd` -rwxr-xr-x. 1 root root 135K 8月 9 2019 /usr/sbin/useradd
[root@localhost ~]# rpm -qc $(rpm -qf $(which useradd)) /etc/default/useradd /etc/login.defs
-
-
使用
read
命令(从键盘输入内容为变量赋值,使用-p
选项来设置提示信息)[root@localhost ~]# read -p "请输入学校:" school 请输入学校:晴花大学 [root@localhost ~]# echo $school 晴花大学
-
变量的作用范围
-
默认情况下定义的变量为局部变量
[root@localhost ~]# school="晴花大学" [root@localhost ~]# echo $school 晴花大学 [root@localhost ~]# bash [root@localhost ~]# echo $school
-
可以使用内部命令
export
将指定的变量导出为全局变量[root@localhost ~]# school="晴花大学" [root@localhost ~]# classes="网络工程" [root@localhost ~]# export school classes [root@localhost ~]# bash [root@localhost ~]# echo $school $classes 晴花大学 网络工程
[root@localhost ~]# export FQDN="www.baidu.com" [root@localhost ~]# echo $FQDN www.baidu.com [root@localhost ~]# bash [root@localhost ~]# echo $FQDN www.baidu.com
-
-
变量的运算
-
在 Bash Shell 环境中,只能进行简单的整数运算,不支持小数运算。整数值的运算主要通过内部命令
expr
进行,运算符与变量之间必须有至少一个空格
-
运算符 | 说明 |
---|---|
+ | 加法运算 |
- | 减法运算 |
\* | 乘法运算,注意不能仅使用“*”符号,否则将被当成文件通配符 |
/ | 除法运算 |
% | 求模运算,又称为取余运算,用来计算数值相除后的余数 |
[root@localhost ~]# X=35
[root@localhost ~]# Y=16
[root@localhost ~]# expr $X + $Y
51
[root@localhost ~]# expr $X - $Y
19
[root@localhost ~]# expr $X \* $Y
560
[root@localhost ~]# expr $X / $Y
2
[root@localhost ~]# expr $X % $Y
3
[root@localhost ~]# Ycube=`expr $Y \* $Y \* $Y`
[root@localhost ~]# echo $Ycube
4096
2、环境变量
-
由系统维护,用于设置用户的工作环境,包括用户宿主目录、命令查找路径、用户当前目录、登录终端等
-
使用 env 命令可以查看到当前工作环境下的环境变量
[root@localhost ~]# env XDG_SESSION_ID=4 HOSTNAME=localhost.localdomain TERM=xterm SHELL=/bin/bash HISTSIZE=1000 SSH_CLIENT=192.168.1.60 63171 22 SSH_TTY=/dev/pts/0 USER=root LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36: MAIL=/var/spool/mail/root PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin #搜索路径 PWD=/root LANG=en_US.UTF-8 HISTCONTROL=ignoredups SHLVL=1 HOME=/root LOGNAME=root SSH_CONNECTION=192.168.1.60 63171 192.168.1.10 22 LESSOPEN=||/usr/bin/lesspipe.sh %s XDG_RUNTIME_DIR=/run/user/0 _=/usr/bin/env
-
搜索路径(PATH变量)
[root@localhost ~]# first.sh -bash: first.sh: command not found [root@localhost ~]# echo $PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin [root@localhost ~]# PATH="$PATH:/root" [root@localhost ~]# first.sh 当前的目录位于: /boot 其中以 vml 开头的文件包括: -rwxr-xr-x. 1 root root 6.5M May 25 2021 vmlinuz-0-rescue-8baa18618aee48cd8dbf18aa34733c14 -rwxr-xr-x. 1 root root 6.5M Aug 8 2019 vmlinuz-3.10.0-1062.el7.x86_64
-
环境变量的全局配置文件为
/etc/profile
,除此之外,每个用户还有自己的独立配置文件(~/.bash_profile
),修改用户的配置文件只会对用户生效
3、位置变量
-
通过命令行给脚本程序传递参数
-
位置变量也称为位置参数,使用1、2、3、·····、9、{10}、{11}、········· 表示。例如,当执行命令行“ls -lh /boot/”时,其中第 1 个位置变量为“-lh”,以“1”表示;第 2 个位置变量为“/boot/”,以“2”表示。命令或脚本本身的名称使用“0”表示,虽然0 与位置变量的格式相同,但是$0 属于预定义变量而不是位置变量
[root@localhost ~]# vim sum.sh #!/bin/bash sum=`expr $1 + $2` echo "$1 + $2 = $sum" [root@localhost ~]# sh sum.sh 12 34 12 + 34 = 46
4、预定义变量
-
Bash中内置的一类变量,不能直接修改
$#:表示命令行中位置参数的个数。 $*:表示所有位置参数的内容。 $?:表示前一条命令执行后的返回状态,返回值为 0 表示执行正确,返回任何非 0值均表示执行出现异常 $0:表示当前执行的脚本或程序的名称。
-
来打包命令行指定的多个文件或目录,并输出相关信息
[root@localhost ~]# vim mybak.sh #!/bin/bash backfile="backup-`date +%s`.tgz" tar zcf $backfile $* &> /dev/null echo "已执行 $0 脚本" echo "共完成 $# 个对象的备份" echo "具体内容包括:$*" #date +%s 获取秒刻时间(从1970年1月1日开始计算)