shell脚本 介绍以及总结
shell的历史
shell概况
人想要和操作系统进行交互,传送指令给操作系统,就需要使用到shell。宏义的shell是人与机器交互的页面,它分为两种,一种是有界面的,比如GUI,另外一种是没有界面的,完全是指令操作的(CLI)。我们一般说的shell指的就是命令行界面。
Bourne shell
最早Ken Thompson设计Unix的时候,使用的是命令解释器,命令解释器接受用户的命令,然后解释他们并执行。
后来出现了Bourne shell(通称为sh),顾名思义,就是一个叫Bourne shell创建的。对,它就是现在我们机器上面的/bin/sh这个可执行文件。这个老哥创建的sh一直沿用至今,现在的UNIX操作系统都配置有sh,而且各种新的shell都会向后兼容sh的语法。
Bourne shell 带来了:
- 脚本可以写在文件里被调用,比如sh a.sh可以执行a.sh里面的shell命令
- 可以交互或者非交互的方式调用
- 可以同步执行也可以异步执行
- 支持输入输出的pipeline,就是管道方式
- 支持输入输出的重定向,就是现在使用的> 和 >>
- 提供一系列内置命令
- 提供流程控制基本的函数和结构
- 弱类型变量,就是可以直接 a=1,不需要指定a为int
- 提供本地和全局的变量作用域
- 脚本执行前不需要编译
- 去掉goto功能
- 使用``进行命令执行替换
- 增加了for~do~done的循环
- 增加了case~in~esac的条件选择
- 文件描述符2>代表错误信息导出
csh, ksh
Bourne老爷子创造的sh非常强大,后来引入的争议是Unix系统是C写的,为什么你的shell的语法不像C呢?然后Bill Joy就编写了C Shell(csh)。它用最类似C的语法来编写shell。后来csh演化成了tchsh,但是csh后面的路途就比较坎坷了,最终未能流行起来。但是现在比如在Mac系统上还保留csh。
Korn Shell(ksh)是1983年出现的,它向后兼容Bourne shell。同时吸取了C shell的一些优点,比如job control。
bash
在1989年,现在最广泛使用的Bash出现了,它的全称叫做Bourne-Again shell。目的是为了与POSIX的标准保持一致,同时保持对sh的兼容。其实现在很多机器上的/bin/sh往往都链接到bash,我们以为我们是使用Bourne shell,实际上我们使用的是Bourne-Again shell。
文件/etc/shells给出了系统中所有已知的shell
/bin/sh 是bash的一个快捷方式
/bin/bash(最多) bash是大多数Linux默认的shell,包含的功能几乎可以涵盖shell所有的功能
/sbin/nologin 表示非交互,不能登录操作系统
/bin/dash 小巧,高效,功能相比少一些
/bin/tcsh 具有C语言风格的一种shell,具有许多特性,但是也有一些缺陷
/bin/csh 是csh的增强版本,完全兼容csh
总结
Shell中的变量
JAVA中的变量:
修饰符 类型 变量名称
private string name="张三";
1.系统变量
$HOME、$PWD、$SHELL、$USER等
2.自定义变量(shell中的变量没有明显的数据类型区分)
普通变量
定义变量:变量名=值 (注意:1.等号两边不要出现空格 2.变量名称不要有特殊字符 3.变量名称不能以数字和特殊字符开头)
读取变量:echo $变量名
撤销变量:unset 变量名
静态变量(一旦创建,只可读): readonly 变量名=值
变量的作用域(只在当前会话和当前用户下有效)
全局环境变量(export)
定义变量:export 变量名=值
全局环境变量的作用域(只在当前会话下的所有用户有效)
系统环境变量
vim /etc/profile
#系统环境变量
export CLASS22=ljh
一定要激活:source /etc/profile
系统环境变量的作用域(针对于所有会话下的所有用户都有效)
查看所有变量
使用set命令
特殊的变量
#!/bin/bash
<<EOF
特殊变量介绍和使用
$n 功能描述:n为数字,$0代表该脚本名称,$1-$9代表第一到第九个参数,十以上的参数,十以上的参数需要用大括号包含,如${10}
$#:获取所有输入参数个数,常用于循环
$*:这个变量代表命令行中所有的参数,$*把所有的参数看成一个整体
$@:这个变量也代表命令行中所有的参数,不过$@把每个参数区分对待
$?:表示读取命令的直接结果状态,返回的变量值为0,说明执行成功,非0则失败
EOF
echo $0 $1 $2 ${11}
echo "参数的个数为:" $#
echo "$/*" $*
echo "$/@" $@
==================================Shell中的数组
JAVA中的数组:
String[] fields={"a","b","c",....}
Shell中的数组:
数组名=(元素 元素 元素 元素 元素) 元素之间以空格分割,索引从0开始,自增
arr=(1 2 3 4 5 6 7)
根据索引读取数组元素:echo ${arr[0]}
获取数据组的长度:echo ${#arr[*]} | echo ${#arr[@]}
获取数组中所有的元素:echo ${arr[*]} | echo ${arr[@]}
修改数组:
(1)可以直接给变量重新赋值
(2)可以根据所有修改数组例如:arr[1]=c
for循环遍历数组
#!/bin/bash
myarray=(1 2 3 4 5 6 7 8 9)
for i in ${myarray[@]}
do
echo $i
done
================运算符
JAVA中的运算:
private int num1=6
private int num2=3
int result=num1/num2
Shell中的运算:
“$((运算式))”或“$[运算式]” + , - , *, /, % 加,减,乘,除,取余
echo $(($A/$B)) | echo $[$A/$B]
echo $(($A+$B)) | echo $[$A+$B]
echo $(($A-$B)) | echo $[$A-$B]
echo $(($A%$B)) | echo $[$A%$B]
echo $[(3+5)*$A]
expr + , - , \*, /, % 加,减,乘,除,取余
注意:expr运算符间要有空格
expr $A \* $B
expr `expr 3 + 5 ` \* $A
小数运算格式
echo $(echo "scale=1;5/2" | bc)
==========Shell中的条件判断
JAVA中的条件判断
private int num1=6
private int num2=3
if(num1>num2){
sout(.....)
}else{
sout(.....)
}
Shell中的条件判断
[ condition ](注意condition前后要有空格)
注意:条件非空即为true,[ jinghang ]返回true,[] 返回false。
(1)两个整数之间比较
= 字符串比较
-lt 小于(less than) -le 小于等于(less equal)
-eq 等于(equal) -gt 大于(greater than)
-ge 大于等于(greater equal) -ne 不等于(Not equal)
[ $A -lt $B ] :比较变量A是否小于变量B
(2)按照文件权限进行判断
-r 有读的权限(read) -w 有写的权限(write)
-x 有执行的权限(execute)
[ -w test06.sh ] : 判断文件是否有可写权限
(3)按照文件类型进行判断
-f 文件存在并且是一个常规的文件(file)
-e 文件存在(existence) -d 文件存在并是一个目录(directory)
[ -f test04.sh ] :判断文件是否存在,并且是一个常规文件
多条件判断:多条件判断(&& 表示前一条命令执行成功时,才执行后一条命令,|| 表示上一条命令执行失败后,才执行下一条命令)
[root@Linux2 class22_shell]# [ -e test100.sh ] || echo "FALSE"
FALSE
[root@Linux2 class22_shell]# [ -e test04.sh ] && echo "TRUE"
TRUE
Shell重中之重点(流程控制)
JAVA if条件判断
private int num1=6
private int num2=3
if(num1>num2){
sout(.....)
}else{
sout(.....)
}
Shell中的条件判断
if [ 条件判断式 ]
then
主体代码
fi
------------------------
if [ 条件判断式 ]
then
主体代码
elif [条件判断式]
then
主体代码
else
主体代码
fi
------------------------------
if [ 条件判断式 ]
then
主体代码
else
主体代码
fi
---------------------
(1)[ 条件判断式 ],中括号和条件判断式之间必须有空格
(2)if后要有空格
完成一个脚本,传入一个文件的名称,如果改文件是一个常规文件
(1)往这个常规文件中写入 bbbb
(2)如果不是常规文件,打印该文件不是常规文件
#!/bin/bash
if [ -f $1 ]
then
echo bbbb >> $1
else
echo "这个文件不是一个常规文件"
fi
完成一个脚本,传入两个参数,
判断参数大小,用大的减小的,
如果相等,则输出两个数值相同
#!/bin/bash
if [ $1 -gt $2 ]
then
echo $[$1-$2]
elif [ $1 -lt $2 ]
then
echo $[$2-$1]
else
echo "两个参数的数值相同"
fi
=======shell中case的使用
JAVA中的switch
int a = 111;
switch(a){
case 111:
.....;
break;
case 222:
.....;
break;
....
default:
.....;
break;
}
面试题
https://www.jianshu.com/p/74e620fa863c (附答案)