简介
-
定义
Shell 是命令解释器
Shell 也是一种程序设计语言,他有变量,关键字,各种控制语句,有自己的语法结构,利用shell程序设计语言可以编写功能很强、代码简短的程序。
基本内容
-
shell的分类和更改
[root@dr ~]# cat /etc/shells
/bin/sh
/bin/bash
/sbin/nologin
/usr/bin/sh
/usr/bin/bash
/usr/sbin/nologin -
查看所有的shell
[root@dr ~]# chsh -l
/bin/sh
/bin/bash
/sbin/nologin
/usr/bin/sh
/usr/bin/bash
/usr/sbin/nologin -
快捷键
Ctrl+a 切换到命令行开始
Ctrl+e 切换到命令行末尾
Ctrl+u 清除剪切光标之前的内容
Ctrl+k 清除剪切光标之后的内容
ctrl+y 粘贴刚才所删除的字符
ctrl+左右键 快速移动光标
Ctrl+r 在历史命令中查找,输入关键字调出之前的命令
Ctrl+l 清屏 -
前台后台作业控制
-
&
命令后面跟&会将执行的命令放到后台执行不影响当前shell的正常工作
[root@dr ~]# sleep 10 [root@dr ~]# sleep 10 & [1] 121021 [root@dr ~]#
[1]是后台任务序号,121021是pid,其中后台任务的序号在后台任务执行完成而没有反馈的到终端显示之前序号不会重新开始。
上面的sleep 10 本意是休眠10秒如果不加&,此时sleep会在前台执行10秒的休眠,若此时我们想要在当前shell再次执行其他命令那么就要等待sleep执行完成,但是如果加上&则不会影响我们当前shell执行其他命令。注意:后台的任务执行完毕时的反馈结果不会直接蹦出来显示,会在你下一次的执行命令时一起出来 -
nohup
nohup (no hang up 不挂起)用于在系统后台不挂断地运行命令,退出终端不会影响程序的运行
在默认情况下(非重定向时),会输出一个名叫 nohup.out 的文件到当前目录下,如果当前目录的 nohup.out 文件不可写,输出重定向到 $HOME/nohup.out 文件中。[root@dr ~]# nohup /root/nohup.sh nohup: 忽略输入并把输出追加到"nohup.out" [root@dr ~]# [root@dr ~]# ls anaconda-ks.cfg nohup.out nohup.sh test [root@dr ~]#
nohup 后面跟命令 如果想要对脚本进行操作,脚本需要具有x执行权限 ;和&配合使用
当一个终端shell在将命令放后台的时候不使用nohup命令进行不挂起操作,那么后台的命令会随着终端的消失而消失,而使用nohup命令则不会 -
Ctrl+c 、Ctrl+z
^c
此命令可以将当前shell终端前台正在运行的命令中断运行相当于kill杀死。
^z
可以将当前shell终端的命令停止运行并放到后台[root@localhost ~]# sleep 10 ^C [root@localhost ~]# jobs [root@localhost ~]# sleep 10 ^Z [1]+ 已停止 sleep 10 [root@localhost ~]# jobs [1]+ 已停止 sleep 10 [root@localhost ~]#
-
bg、fg、kill、jobs
bg %1
将一个放在后台暂停运行的命令变成继续执行,其中%后面跟后台任务的序列号
fg %1
将一个在后台运行的任务调至到前台运行
kill % 1
kill可以杀死后台运行的进程,%后面跟后台进程号
jobs
jobs 可以查看后台的所有进程[root@localhost ~]# sleep 1000 ^Z [1]+ 已停止 sleep 1000 [root@localhost ~]# jobs [1]+ 已停止 sleep 1000 [root@localhost ~]# bg %1 [1]+ sleep 1000 & [root@localhost ~]# jobs [1]+ 运行中 sleep 1000 & [root@localhost ~]# fg %1 sleep 1000 ^Z [1]+ 已停止 sleep 1000 [root@localhost ~]# kill %1 [1]+ 已停止 sleep 1000 [root@localhost ~]# jobs [1]+ 已终止 sleep 1000 [root@localhost ~]# jobs [root@localhost ~]#
-
输入输出重定向
<;1> ;>;2>;&> ;>> ;2>1&
<
标椎输入(stdin) ;
1>
标椎输出(stdout);1通常忽略,同等于>
2>
标椎错误输出(stderr);2不能忽略
2>&1
将标椎错误输出重定向到标准正确输出 效果上同等于&>
注(通常用3>&1 ;fileout 1>out.txt;1>&3 这种方式来创建自己的文件描述符来进行临时的输出重定向)> 与 >>的区别
> 以覆盖的方式重定向到文件中
>> 以追加的方式重定向到文件中 -
管道 |
command1 | command2
管道是将command1命令产生的输出作为command2命令后面的输入,
command1 | xargs -i command2 {}
其中xargs -i 将前面的输出结果传到{}里,这就为作为输入放在合适的位置提供了方便。[root@localhost ~]# ls anaconda-ks.cfg assets mysql_rpm mysql_rpm.zip [root@localhost ~]# ls | grep mysql mysql_rpm mysql_rpm.zip [root@localhost ~]#
- 命令排序
&& || ;
&& || 具有逻辑判断效果
其中&& 前面的执行不成功后面才会执行
|| 前面执行不成功后面才会执行
;无论前面执行成功与否都会执行后面的命令 -
shell通配符
* ? [] () {}
*
匹配任意多个字符
?
匹配任意一个字符
[]
匹配括号中的任意一个字符[1-9][a-z]
()
在当前shell中开辟一个子shell来执行命令,但是会继承当前shell的自定义变量
{}
集合 {1…3} 例如 touch {1…3}.txt会产生1.txt、2.txt、3.txt文件
注意:{}中不能使用变量代替,例如{1…$var}不允许这样使用,因为会先解析{}而不会先解析$var变量 -
脚本的创建与执行
shell脚本的创建没有什么特别的要求,只是习惯性的以sh后缀结尾的文件以用来区别其他文件,其根本和普通文件没有什么区别(linux所有皆文件嘛),执行需要加上x执行权限。
在编写shell脚本的时候第一行会写上#!/bin/bash指定命令解释器
bash脚本的执行,./scripts 相对路径执行 /shelldoc/scripts 使用绝对路径执行 . /scripts 使用当前登录shell执行 source ./scripts 使用当前登录shell执行
进阶内容
- 变量
1.变量类型自定义变量
var=values
生效范围只在当前shell有效
环境变量
定义环境变量 export var=values或者将已有的自定义变量转换成环境变量;
生效范围在当前shell中和其子shell中生效,也就是说子shell继承其环境变量;
引用变量
引用变量使用$ 或者${}
{}是为了区别$后面的变量名是否为一个整体,例如:变量为a 但是用$aaaaa 其中不会识别哪个a是变量哪个是字符串;" " 弱引用 可以实现变量和命令的替换;’ ’ 强引用 不完成变量替换
[root@localhost ~]# aa=1
[root@localhost ~]# echo $aaaaa
[root@localhost ~]# echo ${aa}aaa
1aaa
[root@localhost ~]#
取消变量
unset 变量名
-
变量作用范围
用绝对变量或者相对变量直接运行有执行权限的脚本时,会产生子shell原因是你在编写脚本的时候指定了bash(就是第一行)或者用bash执行时都会产生子shell,这是在当前shell中的自定义变量不会被子shell继承,用source和. 脚本相当于在当前shell中执行这是在子shell和当前shell中的自定义变量可以互相访问。
用export声明的变量可以再当前shell或者子shell中生效但是在其他shell中不生效且当前shell退出时变量自动销毁
想要变量永久生效可以在/etc/profile~/.baserc ~/.bash_profile /etc/bashrc source ~/.bashrc中用export声明变量
注意:当在/etc/profile和用户的.bash_profile中用export声明了当你用su username登录时不会加载用户的环境变量,当用su - username登录时会加载环境变量此时会覆盖掉系统的环境变量。 -
位置变量
$1 $2 …${10}
-
预定义变量
$0 脚本名
$* 所有的参数
$@ 所有的参数
$# 参数的个数
$$ 当前进程的PID
$! 上一个后台进程的PID
$? 上一个命令的返回值 0表示成功5.另
``等价于$()
$(()) 等价于$[ ]
test 等价于 [ ]
在[ ]中比较大小<需要加\转义,而[ [ ] ]不需要
- 流程控制
-
if
基本语法if [条件];then 内容 elif [条件];then 内容 else 内容 fi
-
for
for i in {1..3} do 内容 done 或者 for ((i=0;i<3;i++)) do 内容 done
-
while
while [条件] do 内容 done
-
case
case $var in 1) ;; 2) ;; *) ;; esac
注意:break ,continue,exit,在循环体中执行到break会跳出此循环体,执行到continue时会直接结束本次循环不会执行循环体中continue下面的语句,直接进入下次循环。无论在脚本中的哪个地方执行到exit语句将会退出整个脚本。
-
格式化打印
printf "%-10s %-8s %-4s\n" 姓名 性别 体重kg printf "%-10s %-8s %-4.2f\n" 张三 男 66.1234 printf "%-10s %-8s %-4.2f\n" 李四 男 48.6543 printf "%-10s %-8s %-4.2f\n" 郭芙 女 47.9876
%s %f都是格式替代符
%-10s 指一个宽度为10个字符(-表示左对齐,没有则表示右对齐),任何字符都会被显示在10个字符宽的字符内,如果不足则自动以空格填充,超过也会将内容全部显示出来。
%-4.2f 指格式化为小数,其中.2指保留2位小数。 -
函数
-
创建函数
function(){ 函数体 }
-
调用函数
function $1 $2 $3 ....${10} 写函数名直接调用 其中$1是用来接受第一个参数的,以此类推。
注意:调用函数之前函数必须声明出来,函数在使用位置变量的过程中,使用空格隔开,如果参数中有空格就用引号印起来
- 数组
array=(var1,var2,var3…)
- 遍历数组
for i in ${array[*]} do echo $i done 其中${array[*]}是数组的全部的值 ${!array[*]}是输出全部下标
- 正则表达式
-
基本正则表达式
元字符 功能 示例 ^ 行首定位符 ^love $ 行尾定位符 love$ . 匹配单个字符 l…e * 匹配前导符0到多次 ab*love .* 任意多个字符 [] 匹配指定范围内的一个字符 [lL]ove [ - ] 匹配指定范围内的一个字符 [a-z0-9]ove [^] 匹配不在指定组内的字符 [^a-z0-9]ove \ 用来转义元字符 love. \< 词首定位符 <love \> 词尾定位符 love> \(…\) 匹配稍后使用的字符的标签 :% s/172.16.130.1/172.16.130.5/ x{m} 字符x重复出现m次 o{5} x{m,} 字符x重复出现m次以上 o{5,} x{m,n} 字符x重复出现m到n次 o{5,10} -
扩展正则表达
元字符 功能 示例 + 匹配一个或多个前导字符 [a-z]+ove ? 匹配零个或一个前导字符 lo?ve a b 匹配a或b () 组字符 loveable (…)(…)\1\2 标签匹配字符 (love)able\1er x{m} 字符x重复m次 o{5} x{m,} 字符x重复至少m次 o{5,} x{m,n} 字符x重复m到n次 o{5,10} 注意: grep 使用的是基本正则表达式,使用扩展需要 个grep -E 或者egrep匹配