介绍
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
/etc/shells
/bin/sh
/bin/bash
/usr/bin/sh
/usr/bin/bash
备注:通过查看passwd文件可以看出shell的路径区分sbin和bin;sbin下的shell表示系统账户或者是超级管理员账户,bin下的shell表示普通用
shell脚本的执行方式
echo 输出命令
echo [选项] 内容
选项:
-e 支持反斜杠控制的字符串转换
控制字符 | 作用 |
---|---|
\\ | 输出\本身 |
\a | 输出警告音 |
\b | 退格键,也就是向左删除键 |
\c | 取消输出行末的换行符,和“-n”选项一致 |
\e | ESCAPE键 |
\f | 换页符 |
\n | 换行符 |
\r | 回车键 |
\t | 制表符,也就是tab键 |
\v | 垂直制表符 |
\0nnn | 按照八进制ascll码表输出字符,其中0为数字0,其中nnn是三位八进制数 |
\xhh | 按照十六进制ascll码表输出字符,其中0为数字0,其中hh是两位十六进制数 |
第一个脚本
vi hello.sh
#!/bin/Bash
#the first program
echo -e "hello world"
执行脚本
赋予执行权限,直接运行
chmod 755 hello.sh
./hello.sh
通过bash调用执行脚本
bash hello.sh
备注:windows 回车符合linux的回车符不一样,在window中编写的脚本在linux中打开会显示^M$
,Linux中的回车符&
; 为了解决换行符的问题可以用dos2unix命令解决
dos2unix 脚本名
shell基本功能
历史命令
history [选项] [历史命令保存文件]
选项 :
-c 清空历史命令
-w 把缓存中的历史命令写入历史命令保存文件 ~/.bash_history
历史命令默认保存1000条,可以在环境变量配置文件/etc/profile中进行修改
历史命令不会立即写入到bash_history文件中,只有每次在登出的时候才会写入,默认是存在内存中的
历史命令的调用
- 使用上下箭头调用以前的历史命令
- 使用“!n”重复执行第n条命令
- 使用“!!”重复执行上一条命令
- 使用“!字符串” 重复执行最后一条以该字符串开头的命令
命令别名和常用快捷键
设定命令别名
alias 别名=‘原命令’
查询命令别名
alias
命令的执行顺序
- 第一顺位用绝对路径或相对路径执行的命令
- 第二顺位执行命令
- 第三顺位只是bash内部命令
- 第四顺位执行按照$PATH 环境变量定义的目录,查找顺序找到的第一个命令
让别名永久生效
vim /root/.bashrc
删除别名
unalias 别名
输入输出重定向
标准输入输出
设备 | 设备文件名 | 文件描述符 | 类型 |
---|---|---|---|
键盘 | /dev/stdin | 0 | 标准输入 |
显示器 | /dev/stdout | 1 | 标准输出 |
显示器 | /dev/stderr | 2 | 标准错误输出 |
输出重定向
类型 | 符号 | 作用 |
---|---|---|
输出重定向 | 命令 >文件 | 已覆盖的方式,把命令的输出输出到指定的文件或设备中 |
输出重定向 | 命令 >> 文件 | 以追加的方式,把命令的输出输出到指定的文件或设备中 |
标准错误输出重定向 | 错误命令 2> 文件 | 已覆盖的方式,把命令的错误输出到指定的文件或设备中 |
标准错误输出重定向 | 错误命令 2>>文件 | 以追加的方式,把命令的错误输出到指定的文件或设备中 |
正确输出和错误输出同时保存 | 命令 > 文件 2>&1 | 已覆盖的方式,把正确输出和错误输出都保存在同一个文件中 |
正确输出和错误输出同时保存 | 命令 >>文件 2>&1 | 已追加的方式,把正确输出和错误输出都保存在同一个文件中 |
正确输出和错误输出同时保存 | 命令 &>文件 | 已覆盖的方式,把正确输出和错误输出都保存在同一个文件中 |
正确输出和错误输出同时保存 | 命令 &>>文件 | 已追加的方式,把正确输出和错误输出都保存在同一个文件中 |
正确输出和错误输出同时保存 | 命令 >> 文件1 2>>文件2 | 把正确的输出追加到文件1中,把错误的输出追加到文件2中 |
输入重定向
wc [选项] [文件名]
选项:
-c 统计字节数
-w 统计单词书
-l 统计行数
多命令顺序执行和管道符
多命令顺序执行
多命令执行符号 | 格式 | 作用 |
---|---|---|
; | 命令1;命令2 | 多个命令顺序执行;命令之间没有任何逻辑关系 |
&& | 命令1 && 命令2 | 逻辑与;当命令1正确执行,命令2才会执行,当命令1不正确执行,命令2不会执行 |
|| | 命令1 || 命令2 | 逻辑或;当命令1不正确执行,命令2才会执行,当命令1正确执行,命令2不会执行 |
管道符
命令格式:
命令1 | 命令2
命令1的正确输出作为命令2的操作对象
grep 命令
greo [选项] “搜索内容”
选项:
-i 忽略大小写
-n 输出行号
-v 反向查找
--color=auto 搜索出的关键词用颜色表示
通配符和其他符号
通配符
通配符 | 作用 |
---|---|
? | 匹配任意一个字符 |
* | 匹配0个或多个任意字符,也就是可以匹配任何内容 |
[] | 匹配括号中的任意一个字符,例如:[abc]代表一定匹配一个字符,或者是a,或者是b,或者是c |
[-] | 匹配括号中的任一个字符,-代表一个范围。例如:[a-z]匹配任意一个小写字符 |
[^] | 逻辑非,表示匹配不是括号中的任意字符,例如:[^0-9] 代表匹配一个不是数字的字符 |
bash其他特殊符号
符号 | 作用 |
---|---|
‘’ | 单引号,单引号中所有特殊符号,如’$‘和’`’(反引号)都没有其他特殊的意义 |
“” | 双引号,在双引号中特殊符号都没有特殊的含义,但是“$”,“`”和""是例外,拥有“调用变量值”、“引用命令”、“转义符”的特殊含义 |
`` | 反引号,反引号括起来的内容是系统命令,在bash中会去执行它,和()作用一样,不过推荐使用()作用一样,不过推荐使用()作用一样,不过推荐使用(),因为反引号非常容易看错 |
$() | 和反引号作用一样,用来执行系统命令 |
# | 在shell脚本中,#开头的行代表注释 |
$ | 用于调用变量的值,如需要调用变量name的值时,需要用$name的方式得到变量的值 |
\ | 转义符,在跟\之后的特殊符号将失去特殊含义,变为普通字符。如$将输出“$”符号,而不是当做变量引用 |
shell变量-用户自定义变量
什么是变量
变量是计算机内存的单元,其中存放的知识可以改变的。当shell脚本需要保存一些信息时,如一个文件名,一个数字,就把他存放在一个变量中。每个变量都有一个名字,所以很容易引用他。使用变量可以保存有用的信息,使系统获知用户相关设置,变量也可以用于保存暂时信息。
变量设置规则
- 变量可以是由字母、数字、下划线组成,但不能以数字开头。如果变量名是“2name”则是错误的
- 在bash中,变量的默认类型都是字符串类型,如果要进行数字运算,则必须指定变量的类型为数字类型
- 变量使用等号连接值,等号两侧不能有空格
- 变量的值如果有空格,需要使用单引号或双引号包括。
- 在变量的值中,可以使用""转义符
- 如果需要增加变量的值,那么可以进行变量值的叠加。不过变量名需要使用双引号包含“变量名”或变量名”或变量名”或{变量名}包含
- 如果是把命令的结果作为变量值赋予变量,则需要使用反引号或者$()包含命令
- 环境变量建议大写,便于区分
变量分类
- 用户自定义变量
- 环境变量:这种变量主要保存的是和系统操作环境相关的数据
- 位置参数变量:这种变量主要是用来向脚本当中传递参数或数据的,变量名不能自定义,变量的作用是固定的。
- 预定义变量:是bash中已经定义好的变量,变量名不能自定义,变量作用也是固定的
定义变量
aa=123
调用变量
echo $aa
查看变量
set
删除变量
unset aa
环境变量
环境变量是什么
用户自定义的环境变量值只在当前的shell中生效,而环境变量会在当前的shell和这个shell的所有子shell当中生效。如果把环境变量徐如相应的配置文件,那么这个环境变量就会在所有的shell中生效
设置环境变量
申明变量
export 变量名=变量值
查询变量
env
删除变量
unset 变量名
系统常见环境变量
-
PATH 系统查找命令的路径
[root@MiWiFi-R4CM-srv qilin]# echo $PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
PATH="$PATH":/root/sh
PATH变量叠加 -
PS1:定义系统提示符变量
-
\d:显示日期,格式为“星期 月 日”
-
\h: 显示简写主机名。如默认主机名“localhost”
-
\t:显示24小时制时间,格式为“HH:MM:SS”
-
\T:显示12小时制时间,格式为“HH:MM:SS”
-
\A:显示24小时制时间,格式为“HH:MM”
-
\u:显示当前用户名
-
\w:显示当前所在目录完整名称
-
\W:显示当前所在目录的最后一个目录
-
\#
:之行的第几个命令 -
\$
:提示符。如果是root用户会显示提示符’#’,如果是普通用户会显示提示符“$”
举例:
[root@MiWiFi-R4CM-srv qilin]# echo $PS1 [\u@\h \W]\$ [root@MiWiFi-R4CM-srv qilin]# PS1="[\u@qilin \w]\$ " [root@qilin /home/qilin]$ [root@20:19:53 /home/qilin]$ PS1="[\u@\t \# \w]\$ " [root@20:20:01 113 /home/qilin]$ [root@20:20:01 113 /home/qilin]$ PS1="[\u@\h \W]\$ " [root@MiWiFi-R4CM-srv qilin]$
-
环境变量配置文件
环境变量配置文件简介
环境变量配置文件:主要是用来定义系统操作环境生效的系统默认环境变量;比如PATH,HISTSIZE,PS1,HOSTNAME等默认环境变量;注意:环境变量一般都是大写
source命令
source 配置文件 #修改了配置文件,一般都需要重新登录一次才能生效;如果想不重新登录,使用source 命令直接生效
. 配置文件 # 点和配置文件中有个空格;点相当于source 命令
环境变量配置文件
- /etc/profile
- /etc/profile.d/*.sh
- ~/.bash_profile
- ~/.bashrc
- /etc/bashrc
备注:所有/etc下的配置文件都是针对所有用户
环境变量配置文件的作用
配置文件加载顺序
/etc/profile的作用
- USER变量
- LOGNAME变量
- MAIL变量
- PATH变量
- HOSTNAME变量
- HISTSIZE变量
- umask
- 调用/etc/profile.d/*.sh文件
~/.bash_profile的作用
- 调用了~/.bashrc文件
- 在PATH变量后面加入了“$HOME/bin” 这个目录
注意:在添加环境变量的时候如果不是按照叠加的顺序添加,需要注意加载配置文件的顺序,如果出现重复的环境变量,会因为加载的先后顺序进行覆盖
叠加方式:
PATH=$PATH:$HOME/bin
export PATH
普通方式:
export MY_AGE=18
其他配置文件和登录信息
- ~/.bash_logout 注销时生效的环境变量配置文件
- ~/.bash_history 历史命令保存文件
shell登录信息
本地终端登录欢迎信息:/etc/issue
转义符 | 作用 |
---|---|
\d | 显示当前系统日志 |
\s | 显示操作系统名 |
\l | 显示登录的终端号 |
\m | 显示硬件的体系结构,如i386、i686等 |
\n | 显示主机名 |
\o | 显示域名 |
\r | 显示内核版本 |
\t | 显示当前系统时间 |
\u | 显示当前用户登录的序列号 |
远程终端登录欢迎信息
/etc/issue.net
- 转义符在/etc/issue.net文件中不能使用
- 是否显示次欢迎信息由ssh的配置文件/etc/ssh/sshd_config决定,加入“Banner /etc/issue.net” 才能显示(记得重启ssh服务)
登录后欢迎信息;远程本地登录都生效
vim /etc/motd
位置参数变量
位置参数变量 | 作用 |
---|---|
$n | n为数字,$n代表命令本身,$1-$9代表第一个到第九个参数,十以上的参数需要用大括号包含 |
$* | 这个变量代表命令行中的所有参数,$*把所有的参数看成一个整体 |
$@ | 这个变量也代表命令行中所有的参数,不过$@把每个参数区分对待 |
$# | 这个变量代表命令行中所有参数的个数 |
举例:
#
#例子一
#
#!/usr/bin/bash
echo $0
echo $1
echo $2
#
#例子二
#
#!/usr/bin/bash
echo "total $#"
echo "the parameters is $*"
echo "the parameters is $@"
#执行结果
[root@MiWiFi-R4CM-srv sh]$ ./canshu.sh 1 2 3
total 3
the parameters is 1 2 3
the parameters is 1 2 3
#
#例子三
#
#!/usr/bin/bash
for i in "$*"
#$*中所有参数看成是一个整体,所以这个for循环只会循环一次
do
echo "the parmeters is :$i"
done
x=1
for y in "$@"
#$@中的每个参数是独立的,所以$@中有几个参数就会循环几次
do
echo "the parmeters $x is:$y"
x=$(($x+1))
done
#执行结果
[root@MiWiFi-R4CM-srv sh]$ ./canshu.sh 1 2 4
the parmeters is :1 2 4
the parmeters 1 is:1
the parmeters 2 is:2
the parmeters 3 is:4
预定义变量
预定义变量 | 作用 |
---|---|
$? | 最后一次执行命令返回的状态。如果这个变量的值为0,证明上一个命令正确执行,如果这个变量的值为非0(具体哪个数,由命令自己来决定),则证明上一个命令执行的不正确 |
$$ | 当前进程的进程号(PID) |
$! | 后台运行的最后一个进程的进程号(PID) |
举例
#
#示例一
#
[root@MiWiFi-R4CM-srv sh]$ ls
canshu.sh game.sh hello.sh
[root@MiWiFi-R4CM-srv sh]$ echo $?
0
[root@MiWiFi-R4CM-srv sh]$ dasd
-bash: dasd: 未找到命令
[root@MiWiFi-R4CM-srv sh]$ echo $?
127
#
#示例二
#
#!/usr/bin/bash
echo "the current process is $$"
#输出当前进程的PID,这个PID就是这个脚本志新方式生成的PID
find /home -name hello.sh &
#使用find命令在/home目录下查找hello.sh文件;符号&的意思是把命令放入到后台执行
echo "The last Daemon process is $!"
#执行结果
[root@MiWiFi-R4CM-srv sh]$ ./canshu2.sh
the current process is 3568
The last Daemon process is 3569
[root@MiWiFi-R4CM-srv sh]$ /home/qilin/sh/hello.sh
接收键盘输入
read [选项] [变量名]
选项:
-p “提示信息”:在等待read输入时,输出提示信息
-t 秒数 read命令一直等待用户输入,使用此选项可以指定用户等待时间
-n 字符数 read命令指接收指定的字符数,就会执行
-s 隐藏用户输入的数据,适用于手机密码的输入
举例:
#!/usr/bin/bash
read -t 30 -p "please input your name:" name
echo "Name is $name"
read -t 30 -s -p "please input you age:" age
echo "Age is $age"
read -n 1 -t 30 -p "please select you gender [M/F]:" gender
echo "Gender is $gender"
#执行结果
[root@MiWiFi-R4CM-srv sh]$ ./canshu2.sh
please input your name:qilin
Name is qilin
please input you age:Age is 18
please select you gender [M/F]:mGender is m
bash的运算符
数值运算和运算符
声明变量类型
declare [+/-] [选项] 变量名
选项:
-:给变量设定类型属性
+:取消变量的类型属性
-i:将变量声明为整数类型(integer)
-x:将变量声明为环境变量
-p: 显示指定变量被申明的类型
数值运算方法
举例
#
#方法一
#
[root@MiWiFi-R4CM-srv ~]# a=1
[root@MiWiFi-R4CM-srv ~]# b=2
[root@MiWiFi-R4CM-srv ~]# declare -i c=$a+$b
[root@MiWiFi-R4CM-srv ~]# echo $c
3
[root@MiWiFi-R4CM-srv ~]# declare -p c
declare -i c="3"
#
#方法二
#expr或let数值运算工具
#
[root@MiWiFi-R4CM-srv ~]# a=1
[root@MiWiFi-R4CM-srv ~]# b=2
#c是ab的和,注意:+号两侧必须有空格
[root@MiWiFi-R4CM-srv ~]# c=$(expr $a+$b)
[root@MiWiFi-R4CM-srv ~]# echo $c
3
[root@MiWiFi-R4CM-srv ~]# declare -p c
declare -i c="3"
#
#方法三:
#"$((运算式))"或$"[运算式]"
#
[root@MiWiFi-R4CM-srv ~]# a=1
[root@MiWiFi-R4CM-srv ~]# b=2
[root@MiWiFi-R4CM-srv ~]# d=$(($a+$b))
[root@MiWiFi-R4CM-srv ~]# echo $d
3
[root@MiWiFi-R4CM-srv ~]# e=$[$a+$b]
[root@MiWiFi-R4CM-srv ~]# echo $e
3
运算符
优先级 | 运算符 | 说明 | |
---|---|---|---|
13 | -,+ | 单目负,单目正 | |
12 | !,~ | 逻辑非、按位取反或补码 | |
11 | *,/,% | 乘、除、取模 | |
10 | +,- | 加、减 | |
9 | <<,>> | 按位左移,按位右移 | |
8 | <=,>=,<,> | 小于或等于,大于或等于,小于,大于 | |
7 | ==,!= | 等于,不等于 | |
6 | & | 按位与 | |
5 | ^ | 按位异或 | |
4 | | | 按位或 | |
3 | && | 逻辑与 | |
2 | || | 逻辑或 | |
1 | =,+=,-=,*=,/=,%=,&=,^=,|=,<<=,>>= | 赋值,运算且赋值 |
变量测试与替换
变量置换方式 | 变量y没有设置 | 变量y值为空 | 变量y设置值 |
---|---|---|---|
x=${y-新值} | x=新值 | x为空 | x=$y |
x=${y:-新值} | x=新值 | x=新值 | x=$y |
x=${y+新值} | x为空 | x=新值 | x=新值 |
x=${y:+新值} | x为空 | x为空 | x=新值 |
x=${y=新值} | x=新值 y=新值 | x为空 y值不变 | x=$y y值不变 |
x=${y:=新值} | x=新值 y=新值 | x=新值 y=新值 | x=$y y值不变 |
x=${y?新值} | 新值输出到标准错误输出(就是屏幕) | x为空 | x=$y |
x=${y:?新值} | 新值输出到标准错误输出 | 新值输出到标准错误输出 | x=$y |
举例:
[root@MiWiFi-R4CM-srv ~]# unset y
[root@MiWiFi-R4CM-srv ~]# x=${y-new}
[root@MiWiFi-R4CM-srv ~]# echo $x
new
[root@MiWiFi-R4CM-srv ~]# echo $y
[root@MiWiFi-R4CM-srv ~]# y=baby
[root@MiWiFi-R4CM-srv ~]# echo $x
new
[root@MiWiFi-R4CM-srv ~]# echo $y
baby
[root@MiWiFi-R4CM-srv ~]# x=${y-new}
[root@MiWiFi-R4CM-srv ~]# echo $x
baby
[root@MiWiFi-R4CM-srv ~]# echo $y
baby