一、Shell概述
Shell是什么:Shell是一个命令行解释器,它为用户提供了一个向Linux内核发送请求以便运行程序的界面系统级程序,用户可以用Shell来启动、挂起、停止甚至是编写一些程序。Shell还是一个功能相当强大的编程语言,易编写,易调试,灵活性较强。Shell是解释执行的脚本语言,在Shell中可以直接调用Linux系统命令。
shell的分类
- Bourne Shell:从1979起Unix就开始使用Bourne Shell,Bourne Shell的主文件名为sh。
- C Shell: C Shell主要在BSD版的Unix系统中使用,其语法和C语言相类似而得名。
- Shell的两种主要语法类型有Bourne和C,这两种语法彼此不兼容。Bourne家族主要包括sh、ksh、Bash、psh、zsh;C家族主要包括:csh、tcsh。
- Bash: Bash与sh兼容,现在使用的Linux就是使用Bash作为用户的基本Shell。
Linux支持的shell:可以用命令vim /etc/shells 查看。另外可以直接在命令行中输入sh/bash/csh等Linux支持的命令转换成相应的shell,用exit命令退出。
二、shell脚本的执行方式
echo输出命令:
[root@localhost ~]# echo [选项] [输出内容]
选项 -e: 支持反斜线控制的字符转换
举几个例子如下:注意其中的双引号代表\识别为控制字符具体关于双引号的作用在后续内容中可以查到
[root@localhost ~]# echo -e "ab\bc"
#删除左侧字符
[root@localhost ~]# echo -e "a\tb\tc\nd\te\tf"
#制表符与换行符
[root@localhost ~]# echo -e "\e[1;31m abcd \e[0m"
#输出颜色
#30m= 黑色, 31m= 红色, 32m= 绿色, 33m= 黄色
#34m= 蓝色, 35m= 洋红, 36m= 青色, 37m= 白色
编写脚本:
[root@localhost sh]# vi hello.sh
#!/bin/Bash #此句话不是注释除此以下均是注释
#The first program
# Author: Mr.hao (E-mail: kakaluote@163.com)
echo -e "Mr. hao is the most honest man in the world"
*写好后可以使用 cat -A 文件名 查询脚本的所有内容在linux中回车符识别为$,而windows下编辑回车是^M$。所以有可能发生不匹配。可以使用 dos2unix 文件名 即可转换。
执行脚本的方法:
1.赋予脚本执行权限后利用绝对路径直接运行
[root@localhost sh]# chmod 755 hello.sh
[root@localhost sh]# ./hello.sh #此处./代表当前目录因为我在sh文件夹下
2.通过bash调用执行脚本
[root@localhost sh]# bash hello.sh
此处有疑问:为什么像ls等命令不需要敲出绝对路径就可以执行,具体解答见后内容
三、bash的基本功能
3.1历史命令与命令补全
- 历史命令
[root@localhost ~]# history [选项] [历史命令保存文件]
选项:
-c: 清空历史命令
-w: 把缓存中的历史命令写入历史命令保存文件~/.bash_history
//若不指定文件默认保存在家目录下各个用户的目录当中
历史命令默认会保存1000条,可以在环境变量配置文件**/etc/profile**中找到HISTSIZE=1000进行修改,后续会详细说明这些配置文件的作用。
历史命令的调用:
- 使用上、下箭头调用以前的历史命令
- 使用“!n”重复执行第n条历史命令
- 使用“!!”重复执行上一条命令
- 使用“!字串”重复执行最后一条以该字串开头的命令
- 命令与文件补全:在Bash中,命令与文件补全是非常方便与常用的功能,我们 只要在输入命令或文件时,按“Tab”键就会自动进行补全。
3.2命令别名和常用快捷键
1. 命令别名
[root@localhost ~]# alias 别名='原命令'
#设定命令别名
[root@localhost ~]# alias
#查询命令别名
#此种方法只能暂时生效
命令执行时顺序:
- 第一顺位执行用绝对路径或相对路径执行的命令
- 第二顺位执行别名
- 第三顺位执行Bash的内部命令。bash的自带命令,用whereis cd查找绝对路径时找不到只能找到些帮助文本。
- 第四顺位执行按照$PATH环境变量定义的目录查找顺序找到的第一个命令。
补充:要想调用变量的值需要在变量前加$,PATH是环境变量,可以使用echo $PATH查看此变量的内容。此处可以解答为啥ls可以不用绝对路径即可执行。当敲入ls命令时会在环境变量中去找有没有ls若有则执行,若没有找到则报错。
让别名永久生效
[root@localhost ~]# vi /root/.bashrc
进入此文件按照格式添加即可
删除别名
[root@localhost ~]# unalias 别名
2. Bash常用快捷键
ps:注意ctrl+z和ctrl+c的区别。
3.3输入输出重定向
1. 标准输入输出
2. 输出重定向
ps:有个文件/dev/null可以当垃圾箱使,可以把命令执行结果重定向到这个文件。
3. 输入重定向
[root@localhost ~]# wc [选项] [文件名] #实际上是统计作用
选项:
-c 统计字节数
-w 统计单词数
-l 统计行数
具体用法:
命令<文件 wc < 文件
#把文件作为命令的输入
命令 << 标识符 wc << hello
... hi
... my
标识符 hello
#把标识符之间内容作为命令的输入
3.4多命令顺序执行与管道符
1. 多命令顺序执行
相关例子
[root@localhost tmp]# ls;pwd;date
chinese
c.tar.bz2
japan
systemd-private-5eb5c102c87a4275b13a2a17ee8b342b-chronyd.service-42kHnz
/tmp
2019年 06月 15日 星期六 10:34:40 CST
补充一个命令dd:
#dd:用指定大小的块拷贝一个文件,并在拷贝的同时进行指定的转换。
#它不仅可以复制数据也可以复制文件系统
[root@localhost ~]# dd if=输入文件 of=输出文件 bs=字节数 count=个数
选项:
if=输入文件 指定源文件或源设备
of=输出文件 指定目标文件或目标设备
bs=字节数 指定一次输入/输出多少字节,即把这些字节看做一个数据块
count=个数 指定输入/输出多少个数据块
[root@localhost ~]# date ; dd if=/dev/zero of=/root/testfile bs=1k count=100000 ; date
#可以统计复制的时间
[root@localhost ~]# ls anaconda-ks.cfg && echo yes
[root@localhost ~]# ls /root/test || echo "no
[root@localhost ~]# 命令 && echo yes || echo no
#一些用多命令符的例子
2. 管道符
命令格式:
[root@localhost ~]# 命令1 | 命令2
# 命令 1 的正确输出作为命令 2 的操作对象
相关例子
[root@localhost ~]# ll -a /etc/ | more
[root@localhost ~]# netstat -an | grep "ESTABLISHED"
补一个命令grep
[root@localhost ~]# grep [选项] "搜索内容" 文件名
选项:
-i: 忽略大小写
-n: 输出行号
-v: 反向查找
--color=auto 搜索出的关键字用颜色显示
3.5通配符与其他特殊符号
1. 通配符:用于匹配文件名与正则表达式是有区别的
(注意是完全匹配如一个文件名是abc,当用ls *ab 是查不到这个文件的)
相关例子
[root@localhost ~]# cd /tmp/
[root@localhost tmp]# rm -rf * #从删库到跑路哈哈哈~ 千万别rm -rf /*
[root@localhost tmp]# touch abc
[root@localhost tmp]# touch abcd
[root@localhost tmp]# touch 012
[root@localhost tmp]# touch 0abc
[root@localhost tmp]# ls ?abc
[root@localhost tmp]# ls [0-9]*
[root@localhost tmp]# ls [^0-9]*
2. Bash中其他特殊符号:此处可以回答echo双引号的问题
ps:此处有了新的问题,变量的问题,下面会写
反引号与$()的例子
[root@localhost ~]# echo `ls`
abc anaconda-ks.cfg mailcap-2.1.41-2.el7.noarch.rpm sh usr vimrc
[root@localhost ~]# echo $(ls)
abc anaconda-ks.cfg mailcap-2.1.41-2.el7.noarch.rpm sh usr vimrc
单引号与双引号的例子
[root@localhost ~]# name=cls
[root@localhost ~]# echo '$name'
$name
[root@localhost ~]# echo "$name"
cls
[root@localhost ~]# echo '$(date)'
$(date)
[root@localhost ~]# echo "$(date)"
2019年 06月 15日 星期六 11:30:27 CST
四、bash变量
用户自定义变量,环境变量,位置参数变量,预定义变量
4.1用户自定义变量
1、什么是变量:
变量是计算机内存的单元,其中存放的值可以改变。当Shell脚本需要保存一些信息时,如一个文件名或是一个数字,就把它存放在一个变量中。每个变量有一个名字,所以很容易引用它。使用变量可以保存有用信息,使系统获知用户相关设置,变量也可以用于保存暂时信息。
2、变量设置规则
- 变量名称可以由字母、数字和下划线组成,但是不能以数字开头。如果变量名是“2name”则是错误的
- 在Bash中,变量的默认类型都是字符串型,如果要进行数值运算,则必修指定变量类型为数值型
- 变量用等号连接值,等号左右两侧不能有空格。
- 变量的值如果有空格,需要使用单引号或双引号包括。
- 在变量的值中,可以使用“\”转义符。
- 如果需要增加变量的值,那么可以进行变量值的叠加。不过变量需要用双引号包含“$变量名”或用${变量名}包含。
- 如果是把命令的结果作为变量值赋予变量,则需要使用反引号或$()包含命令。
- 环境变量名建议大写,便于区分。
3、变量分类
- 用户自定义变量
- 环境变量:这种变量中主要保存的是和系统操作环境相关的数据。
- 位置参数变量:这种变量主要是用来向脚本当中传递参数或数据的,变量名不能自定义,变量作用是固定的。
- 预定义变量:是Bash中已经定义好的变量,变
量名不能自定义,变量作用也是固定的。
4、本地变量/用户自定义变量
变量定义
[root@localhost ~]# name="cls"
变量叠加
[root@localhost ~]# aa=123
[root@localhost ~]# aa="$aa"456
[root@localhost ~]# echo $aa
123456
[root@localhost ~]# aa=${aa}789
[root@localhost ~]# echo $aa
123456789
变量调用
[root@localhost ~]# echo $name
变量查看
[root@localhost ~]# set
变量删除
[root@localhost ~]# unset name
4.2环境变量
1、环境变量是什么
用户自定义变量只在当前的Shell中生效,环境变量会在当前Shell和这个Shell的所有子Shell当中生效。如果把环境变量写入相应的配置文件,那么这个环境变量就会在所有的Shell中生效。
2、设置环境变量
export 变量名=变量值
# 申明变量
env
# 查询变量
unset 变量名
# 删除变量
ps:pstree
命令可以查看进程树,yum -y install psmisc可以安装此命令
3、系统常见环境变量
PATH:系统查找命令的路径
[root@localhost ~]# echo $PATH
/usr/lib/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
[root@localhost ~]# PATH="$PATH":/root/sh #PATH 变量叠加
#当然也可以把shell文件复制到已经有的路径当中,但我们一般不这么做会让别人以为是系统命令。
ps:此处可以解决自己写的shell脚本必须写绝对路径的问题,TAB键命令补全主要也是靠PATH。
PS1:定义系统提示符的变量
\d:显示日期,格式为“星期 月 日”
\h:显示简写主机名。如默认主机名“localhost”
\t:显示24小时制时间,格式为“HH:MM:SS”
\T:显示12小时制时间,格式为“HH:MM:SS”
\A:显示24小时制时间,格式为“HH:MM”
\u:显示当前用户名
\w:显示当前所在目录的完整名称
\W:显示当前所在目录的最后一个目录
\#:执行的第几个命令
\$:提示符。如果是root用户会显示提示符为“#”,如果是普通用户会显示提示符为“$”
\@:显示时分 上午/下午
举几个例子
[root@localhost ~]# PS1='[\u@\t \w]\$ '
[root@04:50:08 /usr/local/src]#PS1='[\u@\@ \h \# \W]\$ '
[root@04:53 上午 localhost 31 src]#PS1='[\u@\h \W]\$ '
4.3位置参数变量
例子1:
#!/bin/bash
num1=$1
num2=$2
sum=$(( $num1 + $num2)) #此处注意格式 运算符后边会讲
# 变量 sum 的和是 num1 加 num2
echo $sum
# 打印变量 sum 的值
例子2:
#!/bin/bash
echo "A total of $# parameters"
# 使用 $# 代表所有参数的个数
echo "The parameters is: $*"
# 使用 $* 代表所有的参数
echo "The parameters is: $@"
# 使用 $@ 也代表所有参数
例子3:$*与$@的区别
#!/bin/bash
for i in "$*"
#$* 中的所有参数看成是一个整体,所以这个 for 循环只会循环一次
do
echo "The parameters is: $i"
done
x=1
for y in "$@"
#$@ 中的每个参数都看成是独立的,所以“ $@ ”中有几个参数,就会循环几次
do
echo "The parameter$x is: $y"
x=$(( $x +1 ))
done
ps:我自己在centos 7上写的都是区别对待了啊啊啊啊啊!!!!,两个结果一样啊
4.4 预定义变量
1、预定义变量
ps:$?就是&&判断第一条命令是否执行正确的方法
例子
#!/bin/bash
# Author: cls (E-mail: cls@japanese.net)
echo "The current process is $$"
# 输出当前进程的 PID 。
# 这个 PID 就是 variable.sh 这个脚本执行时,生成的进程的 PID
find /root/sh -name hello.sh &
# 使用 find 命令在 root 目录下查找 hello.sh 文件
# 符号 & 的意思是把命令放入后台执行,工作管理我们在系统管理章节会详细介绍
echo "The last one Daemon process is $!"
2、接收键盘输入
[root@localhost ~]# read [选项] [变量名]
选项:
-p “提示信息”:在等待read输入时,输出提示信息
-t 秒数: read命令会一直等待用户输入,使用
此选项可以指定等待时间
-n 字符数: read命令只接受指定的字符数,就会执行
-s: 隐藏输入的数据,适用于机密信息的输入
例子
#!/bin/bash
# Author: cls (E-mail: cls@japanese.net)
read -t 30 -p "Please input your name: " name
# 提示“请输入姓名”并等待 30 秒,把用户的输入保存入变量 name 中
echo "Name is $name "
read -s -t 30 -p "Please imput your age: " age
# 年龄是隐私,所以我们用“ -s ”选项隐藏输入
echo -e "\n"
echo "Age is $age "
read -n 1 -t 30 -p "Please select your gender[M/F]: " gender
# 使用“ -n 1 ”选项只接收一个输入字符就会执行(都不用输入回车)
echo -e "\n"
echo "Sex is $gender"
五、bash变量相关知识
5.1数值运算与运算符
1、declare声明变量类型
[root@localhost ~]# declare [+/-][选项] 变量名
选项:
-: 给变量设定类型属性
+: 取消变量的类型属性
-i: 将变量声明为整数型(integer)
-x: 将变量声明为环境变量
-p: 显示指定变量的被声明的类型
2、数值运算—方法1
[root@localhost ~]# aa=11
[root@localhost ~]# bb=22
# 给变量 aa 和 bb 赋值
[root@localhost ~]# declare -i cc=$aa+$bb
方法2:expr或let数值运算工具
[root@localhost ~]# aa=11
[root@localhost ~]# bb=22
# 给变量 aa 和变量 bb 赋值
[root@localhost ~]# dd=$(expr $aa + $bb)
#dd 的值是 aa 和 bb 的和。注意“ + ”号左右两侧必须有空格
方法3:“$((运算式))”或“$[运算式]”
[root@localhost ~]# aa=11
[root@localhost ~]# bb=22
[root@localhost ~]# ff=$(( $aa+$bb ))
[root@localhost ~]# gg=$[ $aa+$bb ]
3、运算符例子
[root@localhost ~]# aa=$(( (11+3)*3/2 ))
# 虽然乘和除的优先级高于加,但是通过小括号可以调整运算优先级
[root@localhost ~]# bb=$(( 14%3 ))
#14 不能被 3 整除,余数是 2
[root@localhost ~]# cc=$(( 1 && 0 ))
# 逻辑与运算只有想与的两边都是 1 ,与的结果才是 1 ,否则与的结果是0
5.2 变量测试与内容替换
例子
自己敲,哼~
六、环境变量配置文件
6.1 环境变量配置文件简介
1、source命令:使配置文件直接生效而不用重启。
[root@localhost ~]# source 配置文件
或
[root@localhost ~]# . 配置文件 #注意点后有空格
2、环境变量配置文件简介
环境变量配置文件中主要是定义对系统的操作环境生效的系统默认环境变量,比如PATH、HISTSIZE、PS1、HOSTNAME等默认环境变量。
ps:前面说的只能暂时保存只有写进环境变量配置文件才能永久生效。
/etc/profile
/etc/profile.d/*.sh
/etc/bashrc
#以上三个文件对所有用户都生效
~/.bash_profile
~/.bashrc
#以上两个文件只能对相应用户生效
6.2 环境变量配置文件作用
1、环境变量配置文件执行顺序
/etc/profile的作用
- USER变量
- LOGNAME变量:
- MAIL变量:
- PATH变量:
- HOSTNAME变量:
- HISTSIZE变量:
- umask:
- 调用/etc/profile.d/*.sh文件
~/.bash_profile的作用
- 调用了~/.bashrc文件。
- 在PATH变量后面加入了“:$HOME/bin”这个目录
~/.bashrc的作用
- 定义默认别名
- 调用/etc/bashrc
/etc/bashrc的作用
环境变量配置并没有重叠因为重叠部分是针对no login shell
- PS1变量
- umask
- PATH变量
- 调用/etc/profile.d/*.sh文件
6.3 其他配置文件和登录信息
1、注销时生效的环境变量配置文件
- ~/.bash_logout
2、其他配置文件
- ~/bash_history
3、Shell登录信息
-
本地终端欢迎信息: /etc/issue
-
远程终端欢迎信息: /etc/issue.net
注意: 转义符在/etc/issue.net文件中不能使用,是否显示此欢迎信息,由ssh的配置文件/etc/ssh/sshd_config决定,加入“Banner/etc/issue.net”行才能显示(记得重启SSH服务) -
登陆后欢迎信息:/etc/motd:
不管是本地登录,还是远程登录,都可以显示此欢迎信息