一. Shell执行方式
交互式:解释执行用户的命令,用户输入一条,shell就解释执行一条
批处理:用户先写一个Shell脚本,其中有很多条命令,让Shell一次把这些命令执行完。
注意:使用普通用户运行Shell
二. 脚本
sh:是Unix标准默认的shell
ash:Linux中占用系统资源最少的一个小shell,只包含24个内部命令
csh:是Linux比较大的内核,共有52个内部命令,指向tcsh
ksh:共有42条内部命令,最大的优点是几乎和商业发行版的ksh完全兼容
三. 程序设计语言
1.编译型语言
很多传统的程序设计语言,如java、c、c++都是编译型语言,这类语言需要预先将我们写好的源代码转换成目标代码,这个过程被称作编译;
优点:运行程序时,直接读取目标代码,由于编译后的目标代码非常接近计算机底层,因此执行效率很高
缺点: 由于编译型语言多半运作于底层,所处理的是字节、整数、浮点数或是其他机器层级的对象,往往实现一个简单的功能需要大量复杂的代码
2.解释型语言
解释型语言也被称作脚本语言,执行这类程序时,解释器需要读取我们编写的源代码,并将其转换成目标代码,再由计算机运行,因为每次执行程序都多了编译的过程,效率有所下降;
优点:多半运行在比编译型语言还高的层级,能够轻易处理文件与目录之类的对象
缺点:效率不如编译型语言
四. shell变量
1.自定义变量
variableName=“value”
注意:变量名和等号之间不能有空格;首个字符必须为(a-z,A-Z),中间不能有空格,可以使用下划线,不能使用标点符号,不能使用bash里的关键字
2.使用变量
使用一个定义过的变量,在变量名前面加$
echo $valiableName
echo ${valiableName}
花括号可选,加花括号为了帮助解释器识别变量的边界
3.重新定义变量
variableName=“秋名山”
4.只读变量
使用 readonly 命令将变量定义为只读,只读变量的值不能被改变
5.删除变量
使用unset命令可以删除变量
unset variableName
变量删除后不能再次使用,unset命令不能删除只读变量
6.变量类型
1. 局部变量
在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量
2. 环境变量
所有的程序,包括 shell 启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行。必要的时候 shell 脚本也可以定义环境变量
3. shell变量
shell 变量是由 shell 程序设置的特殊变量。shell 变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了 shell 的正常运
7.特殊变量
$ : 表示当前shell进程的ID
$0 : 当前脚本的文件名
$n:传递给脚本或函数的参数,命令行参数
$#:传递给脚本或函数的参数个数
$*:传递给脚本或函数的所以参数
$@:传递给脚本或函数的所以参数
$?:上个命令的退出状态,或函数的返回值
$$:当前shell的进程ID
$* 和 $@的区别:用双引号包含时,*会把所以参数作为一个整体,@会把每个参数分开
五. shell替换
1. 转义字符替换
\ | 反斜杠 |
---|---|
\a | 警报 |
\b | 退格 |
\f | 换页 |
\n | 换行 |
\r | 回车 |
\t | 水平制表符 |
\v | 垂直制表符 |
-e 表示对转义字符进行替换,不使用-e,将会原样输出
-E 禁止转义
2.命令替换
使用反引号 ``
DATA=data
echo “Data is ${DATA}”
3.变量替换
${var} | 变量本来的值 |
---|---|
${var:-word} | 如果变量var为空或被删除,那么返回word,但不改变var的值 |
${var:=word} | 如果变量var为空或被删除,那么返回word,var的值设置为word |
${var:?message} | 如果变量var为空或被删除,那么将消息message送到标准错误输出,可以用来检测变量var是否可以被正常赋值若此替换出现在shell脚本中,那么脚本将停止运行 |
${var:+word} | 如果变量var被定义,那么返回word,但不改变var的值 |
六. shell运算符
注意:表达式和运算符之间要有空格,完整的表达式要被``包含
1. 算术运算符
+ | - | * | / | % | = | == | != |
---|---|---|---|---|---|---|---|
加 | 减 | 乘 | 除 | 取余 | 赋值 | 相等 | 不相等 |
2. 关系运算符
-eq | -ne | -gt | -lt | -ge | -le |
---|---|---|---|---|---|
相等true | 不相等true | 大于true | 小于true | 大于等于 | 小于等于 |
3.布尔运算符
! | -o | -a |
---|---|---|
非运算 | 或运算 | 与运算 |
4. 字符串运算符
= | != | -z | -n | str |
---|---|---|---|---|
判断字符串是否相等true | 判断字符串是否不相等 | 判断字符串长度是否为0 | 判断字符串长度是否不为0 | 判断字符串是否为空,不空true |
用中括号括住 【】
5. 文件测试运算符
-b file | 检测文件是否是块设备文件 |
---|---|
-c file | 是否是字符设备文件 |
-d file | 是否是目录 |
-f file | 是否是普通文件 |
-g file | 是否设置了SGID位 |
-k file | 是否设置了粘着位 |
-p file | 是否是具名管道 |
-u file | 是否设置了SUID位 |
-r file | 是否可读 |
-w file | 是否可写 |
-x file | 是否可执行 |
-s file | 是否为空 |
-e file | 是否存在 |
七. shell注释
以 # 开头
八. shell字符串
1. 单引号
限制:单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的,单引号字符串中不能出现单引号
2. 双引号
优点:双引号里可以有变量,可以出现转义字符
3. 获取字符串长度
string=“abcd”
echo ${#string}
4. 提取子字符串
string=“alibaba is graet”
echo ${string:1:4}
查找子字符串
string=“alibaba is a great”
echo `expr index "$string"is`
九. shell数组
bash支持一维数组,不支持多维数组,并且没有限定数组的大小,下标由0开始
1.定义数组
array_name=(value1 … valuen)
用括号来表示数组,数组元素用空格符号分割
2.读取数组
valuen=${array_name[2]}
用@或*可以获取数组中的所有元素
{array_name[*]} || {array_name[@]}
3.获取数组的长度
${#array_name[*]}
十. shell printf命令
printf命令用于格式化输出,是echo命令的增强版
$ printf “%s and %d \n”
结果:and 0
%s用null替换 %d用0替换
十一. 循环语句
1.if … else
if...else...fi
if...elif...else...fi
if []
then
...
else
...
fi
if … else 经常与test命令结合使用,test命令用于检查某个条件是否成立,与方括号类似
2.case … esac
case … esac 与switch … case语句类似
case 值 in
模式1)
command1
command2
;;
模式2)
command1
;;
*)
command1
;;
esac
3.for循环
for 变量 in 列表
do
command1
...
commandN
done
列表是一组值,值通过空格分割
4.while循环
while command
do
...
done
5.until循环
执行一系列命令直到条件为true时停止,until与while循环在处理上刚好相反
until command
do
...
done
6.break和continue命令
break允许跳出所有循环,后跟整数,表示跳出第几层循环
continue仅仅跳出当前循环,后跟整数,表示跳出第几层循环
十二.shell函数
shell函数返回值只能是整数,一般用来表示函数执行成功与否,如果要返回字符串,可以先定义一个变量,用来接收函数的计算结果
删除函数 unset .f function_name 要加 .f 选项
如果要在终端调用函数,可以将函数定义在主目录下的.profile文件,每次登录后,在命令提示符后面输入函数名字可以立即调用
函数参数
通过$n的形式获取参数的值
注意:当n>=10,需要使用${n}来获取参数
十三. shell文件包含
shell中包含脚本可以使用 . filename 或 source filename
注意 : 点和文件名中间有一空格,被包含的脚本不需要有执行权限
十四. 补充
1. cut命令
-b :以字节为单位进行分割。这些字节位置将忽略多字节字符边界,除非也指定了 -n 标志。
-c :以字符为单位进行分割。
-d :自定义分隔符,默认为制表符。
-f :与-d一起使用,指定显示哪个区域。
-n :取消分割多字节字符。仅和 -b 标志一起使用。如果字符的最后一个字节落在由 -b 标志的 List 参数指示的范围之内,该字符将被写出;否则,该字符将被排除
cut最常用的选项是-d和-f的组合。它基本上会根据特定的分隔符和列出的字段提取内容
cut -d ':' -f 1 /etc/passwd #打印/etc/passwd文件中每一行的第一个字段
2. sed命令
3. awk命令
4. test命令
用于检查某个条件是否成立,可以进行数值、字符、文件三个方面的测试,与 【】功能类似
十五.shell提取文件名
使用 ${}
1. ${var##*/}
var=/dir1/dir2/file.txt
echo ${var##*/}
结果:file.txt
2. ${var##*.}
var=/dir1/dir2/file.txt
echo ${var##*.}
结果:txt
3. ${var#*.}
var=/dir1/dir2/file.tar.gz
echo ${var#*.}
结果:tar.gz
4. ${var%%.*}
var=/dir1/dir2/file.txt
echo ${var%%.*}
结果:/dir1/dir2/file
5. ${var%/*}
var=/dir1/dir2/file.txt
echo ${var%/*}
结果:/dir1/dir2
#:表示从左边算起第一个
%:表示从右边算起第一个
##:表示从左边算起最后一个
%%:表示从右边算起最后一个
basename
basename命令的作用是从路径中提取出文件名,使用方法为
basename NAME [SUFFIX];
若只想提取出文件名file,而不带有后缀,还可以在变量的后面加上后缀名
var=/dir1/dir2/file.txt
echo $(basename $var)
结果: file.txt
echo $(basename $var .txt)
结果: file
dirname
dirname命令的作用是从路径中提取出目录名,使用方法为
dirname NAME
该命令不仅能提取出普通文件所的目录,它能提取出任何文件所在的目录,例如目录所在的目录
var=/dir1/dir2/
dirname $var
结果:/dir1