1、什么是shell?
shell是用户与系统交互作用的界面。shell是一种命令解释程序,同时也是一种高级程序设计语言。
2、shell的种类?
sh-是unix的默认shell,也是其它shell的开发基础,再编程方面很优秀,但是在处理和用户的交互方面不如其它的shell。
csh-语法与c类似。提供了sh所不能处理的用户交互特征。
ksh-结合了csh和sh的特点,并且和sh完全向下兼容。效率很高,其命令交互界面和编程交互界面很好
bash-linux系统中默认的shell,和sh兼容,还继承了csh,ksh的有点。如命令补全,命令行历史,命令行编辑
3、shell脚本的执行方式
shell脚本有三种执行方式
1)输入定向到shell脚本,其一般形式是:
bash<脚本名
如:bash<my.sh
2)以脚本名作为bash参数,其一般形式是:
bash 脚本名 参数
如果以目前shell执行一个脚本,则可以使用如下形式:
. 脚本名
如:bash my.sh
. my.sh
3)将shell脚本的权限设置为可执行,然后直接在提示符虾运行
chmod a+x my.sh
./my.sh
4、命令历史
系统为每个用户维护一个命令历史文件:~/.bash_history。
显示历史命令:
1)history 不带参数,则history则会显示历史命令的清单
2)history 50 ,只显示历史表中最后50个命令
3)history al,把al作为历史文件名
执行历史命令:
1)!!重复最后一条命令
2)!n执行第n条命令
3)!-n执行倒数第n条命令
4)!string执行以string开头的最近的历史命令
5)!?string?执行最近的,包含string的那条历史命令
6)!#到现在为止所输入的整个命令行
5、名称补全
当在命令行上输入部分目录活文件名并按下tab之后,可能出现下述情况:
1)如果系统唯一确定那个文件或目录,则自动补全
2)如果linux找到了不只一个文件,则会把文件名补全到这些文件名中相同部分的最后一个字符
3)如果根据已输入的字符不能唯一确定相应的名称时,会尽量补全后面的字符,然后响铃提示,要求用户进一步输入名字后面的字符
6、别名
1)定义别名
alias name=value 如:alias cp='cp -i'
定义别名时,在赋值号两边不能有空格。定义别名时,往往用单引号将代表的内容括起来,从而防止shell对其中的内容产生歧义,如对空格和特殊字符另做解释。
2)取消别名
unalias name
如:unalias ll
与alias异样,unalias也可以在一个命令上同时取消多个别名的定义,只需在unalias之后依次列出要取消的别名名称。
也可以一次将所有的别名都从别名表中删除,使用如下命令:
unalias -a
7、shell特殊字符
1)通配符
(1)一般通配符
a、* 匹配任意字符的0次或多次出现
b、? 匹配任意一个字符
c、[] 其中有一个字符组。其作用是匹配该字符组所限定的任何一个字符
d、! 如果它紧跟在一对方括号的左方括号之后,则表示不在一对方括号中所列出的字符。
(5)模式表达式
a、*模式表匹配给定模式表中模式的0次或多次出现,各模式之间以|分开。
b、+模式表匹配给定模式表中模式的1次或多次出现,各模式之间以|分开
c、?模式表匹配模式表中任何一种模式的0次或1次出现,各模式之间以|分开。
d、@模式表匹配模式表中给定模式的一次出现,各模式之间以|分开。
e、!模式表 除给定模式表中的模式之外,可以匹配任何其他东西
2)引号
在shell中引号分为三种:单引号、双引号和倒引号
(1)双引号
由双引号括起来的字符(除`,$,\)均作为普通字符对待。这三个字符仍保留其特殊功能,即$表示变量代替;倒引号表示命令替换;反斜线-仅当后面跟的是$,`,",\或换行符之一时,\才是转移字符。
(2)单引号
由单引号括起来的字符都作为普通字符出现。
(3)倒引号
倒引号括起来的字符串被shell解释为命令行,在执行时,shell会先执行该命令,并以他的标准输出结果代替整个倒引号部分。进行置换时,倒引号中可以是单条命令,也可是多条命令的组合,如管道线等。另外,倒引号还可以嵌套使用。但应注意,嵌套使用时内层的倒引号必须用反斜线将其转义。
未用引号括起来的反斜线和换行符组合作为续行符使用。如果他们放在一行的行尾,那么这一行就和下面一行被视为同一行。
3)输入输出重定向
(1)输入重定向符
输入重定向<作用是把命令的标准输入重新定向到指定文件。
(2)输出重定向
输出重定向>作用是把命令的标准输出重新定向到指定文件。
shell脚本的输出也可以重新定向到指定文件。如果不同命令的输出都定向到同一个文件,那么,只有最后命令的输出保留在该文件中,而文件原有的内容被新内容冲掉了。如果定向的目标文件是一个普通文件,并且原来他不存在,那么就建立一个新文件。文件名也可以是I/O设备名。
(3)输出附加定向符
>>作用是把命令的输出附加到指定文件的后面。
(4)即时文件定向符
即使文件是由重新定向符<<,一对标记符以及其中的若干输入行组成。它允许把shell程序的输入行重新定向到一个命令中。其格式为:
命令 [参数]<<标记符
输入行
...
标记符
如
mail $1<<!!
best wishes to you!
!!
(5)与文件描述字相关的重定向
系统为每个进程自动打开三个标准文件,其文件描述字分别为0,1,2。
标准输出和标准错误输出可以重新定向到同一个文件,一般形式是:
command &>file
等价于:
command>file 2>&1
关于shell中:>/dev/null 2>&1 详解
shell中可能经常能看到:>/dev/null 2>&1
命令的结果可以通过%>的形式来定义输出
分解这个组合:“>/dev/null 2>&1” 为五部分。
1:> 代表重定向到哪里,例如:echo "123" > /home/123.txt
2:/dev/null 代表空设备文件3:2> 表示stderr标准错误4:& 表示等同于的意思,2>&1,表示2的输出重定向等同于15:1 表示stdout标准输出,系统默认值是1,所以">/dev/null"等同于 "1>/dev/null"因此,>/dev/null 2>&1也可以写成“1> /dev/null 2> &1”和 "&>/dev/null"
4)注释,管道线,后台命令
在一条命令的最后输入&符号,告诉shell在后台启动该程序。shell马上显示主提示符,提醒可以输入新的命令。
5)命令执行操作符
(1)顺序执行
命令可以在一行输入,各命令之间以;隔开。
(2)&&与
命令1&&命令2
先执行命令1,如果执行成功,才执行命令2;否则,若命令1执行不成功,则不执行命令2。应注意,命令执行成功时返回值为0,若执行不成功,返回非0。
(3)||或
命令1||命令2
先执行命令1,如果执行不成功,则执行命令2,否则不执行命令2。
6)成组命令
在shell中有两种方式可以将若干命令组合在一起,使其在逻辑上被视为一条命令。{}和()
(1){}
以{}括起来的全部命令可视为语法上的一条命令,出现在管道符的一边。使用{}注意,{后面应有一个空格,}之前应有一个;
(2)()
用()括起成组命令时,(后不必有空格,)之前也不需加;
用{}括起来的成组命令只在本shell内部执行,不产生新的进程;而用()括起来的成组命令是在新的子shell执行,要建立新的子进程。因此,在()内的命令不会改变父shell的变量值及工作目录等。
6、shell变量
shell有两类变量:环境变量和临时变量。环境变量是永久性变量,临时变量在shell程序内部定义,其使用范围仅限于定义他的程序。
1)用户定义的变量
变量名=value
=两边没有空格,变量的值可以改变,只需重新赋值。
引用变量的时候,需在变量名前加$。如果没有value,变量名=,则赋值空串,未明确赋值的变量也仅含空串。变量名区分大小写。如果在赋给变量的值中要含有空格,制表符或换行符,那么,就应该用"将字符串括起来。
一个变量的值可以作为某个长字符串中的一部分。如果变量必须出现在长字符串的开头或中间,应使用花括号将变量名括起来。
可以将一个命令的执行结果赋值给变量。有两种形式的替换
变量名=`命令表`
变量名=$(命令表)
2)数组
bash只提供一维数组。用户可以直接对数组变量赋值。
数组名[下标]=value
也可以显式声明:
declare -a 数组名
或者
数组名=(value1 value2 value3...)
读取数组元素值的一般格式是:
${数组名[下标]}
使用*或@作为下标,则会以数组中所有元素取代。
利用命令unset可以取消一个数组的定义。例如,unset week[4],unset week,unset week[*]。
3)变量引用
$name
${name}
${name[n]}
${name[*]},${name[@]}-数组中所有非空元素,如果用双引号把他们都括起来,对于"${name[*]}"被扩展成一个词。"${name[@]}"被扩展成多个词。
var=${name:-word}如果name为空,则var等于word,name不变。否则,var等于name。
var=${name:=word}如果name为空,则var和name都取word的值。否则var取name的值,name不变。
var=${name:?word}如果name为空,则变量var不取值,否则var取值name,name保持不变。
var=${name:+word}如果name为空,则var和name都为空;否则,var取word的值,而name不变。
${name#pattern}去掉前面和pattern相同的地方,取最少的部分
${name##pattern}去掉前面和pattern相同的地方,取最多的部分
${name%pattern}去掉后面和pattern相同的地方,取最少的部分
${name%%pattern}去掉后面和pattern相同的地方,取最多的部分
{#*}分别是 #返回参数的个数
${#name[i]}name中第i各元素的长度
${#name[*]},${#name[@]}name中已经设置的元素的个数
4)输入输出命令
(1)read命令,变量个数和数据个数
a、相同,则依次对应赋值
b、变量个数少于数据个数,则从左至右赋值,最后一个变量被赋值所有的剩余数据
c、变量个数多余给定个数,则依次赋值,其它取空串
(2)echo命令,如果echo命令带有选项-e,那么在其后的参数可以有以下转义字符:\a响铃报警 \b退一个字符位置 \c光标不换行,新的输出信息接在该行的后面。
5)位置参数
(1)位置参数及其引用
$0脚本名,$1第一个参数,$2第二个参数...
(2)用set命令为位置参数赋值
在shell程序中可以利用set命令为位置参数赋值或重新赋值。例如:set m1.c m2.c m3.c把字符串m1.c给$1,m2.c给$2...$0不能用set命令赋值。
6)移动位置参数
shift命令。shift命令可以带有一个整数作为参数,例如,shift3的功能,每次把位置参数右移3位。
7)预先定义的特殊变量
$#参数的个数
$?上一条命令执行后的返回值。
$$当前进程的进程号
$!上一个后台命令对应的进程号
$-由当前shell设置的执行标志名组成的字符串。如set -xv。
$*表示在命令行中实际给出的所有实参字符串
$@和$*相同
8)环境变量
(1)常用的环境变量
可以用env命令列出已经定义的所有环境变量。
HOME-用户主目录
LOGNAME-用户的登录名
MAIL-系统信箱的路径
PATH
PS1-shell的主提示符
PWD-当前路径
SHELL-当前shell
TERM-终端类型
9)环境文件.bash_profile,.bashrc,.bash_logout
10)export语句与环境设置
export语句:为了使其后的各个子进程能继承父进程中定义的变量,就必须用export命令将这些变量送入进程转出区。
环境变量的设置和显示:可以创建一个新的环境变量或改变已有的环境变量的值。设置变量要用如下形式:
变量名=value
利用不带参数的export命令可以显示本进程利用export命令所输出的全部变量名及其值
set命令
显示迄今为止所定义的全部变量,包括局部变量和公用变量
用来设置位置参数的值
改变执行shell脚本时的选项设定,可以使用户改变shell的功能,如set -xv。
x,该标志设置后,使shell对以后各命令行在完成参数替换且执行该行命令之前,先显示该行的内容。
v,该标志设置后,使shell对以后各个语句行都按原样现在屏幕上显示出来,然后才对命令行予以执行,并显示相应结果。
x标志的作用是仅跟踪哪些实际正在执行的命令,而v标志则显示该set语句之后的每一个语句航
7、算术运算
bash中执行整数算术运算的命令是let,其语法格式为:
let arg...
当表达式中有特殊字符时,必须用双引号将其括起来。
let命令等价于((...))
凡是let命令的地方都可以用((...)) 替代,但其中只能包含一个算术表达式,并且只有使用$((算术表达式)),才能返回表达式的值。
8、控制结构
1)if语句
if 测试条件
then
elif
else
fi
通常,if语句的测试条件部分都是用test命令实现的。其实,条件测试可以利用一般命令执行成功与否来判断。如果命令正常结束,则表示执行成功,其返回值为0,条件测试为真;如果命令执行不成功,则返回值不为0,条件测试就为假。所以if的更一般形式:
if 命令表1(可以为多个命令,值为最后一个命令的退出值)
then
else
fi
2)条件测试
条件测试有三种形式:一种用test命令,一种是[]括起来,[之后, ]之前都应该有空格,第三种形式是[[ ]]
有关文件方面的测试:
-r 文件可读
-w 文件可写
-x 文件可执行
-f 文件是普通文件
-d 目录文件
-p FIFO文件
-b 块设备文件
-c 字符设备文件
-s 文件长度不为0
-t 若文件被打开且文件描述字与终端设备相关
有关字符串方面的测试:
-z s1 长度为0
-n s1 长度不为0
s1 不是空串
s1=s2 或 s1==s2
s1!=s2
s1<s2 字典排序
s1>s2 字典排序
有关数值方面的测试: -eq 等于
-ne 不等于
-lt 小于
-le 小于等于
-gt 大于
-ge 大于等于
逻辑运算符:
!非
-a 与
-o 或
可以用圆括号将表达式括起来,使之成为一个整体,优先得到运算
[ \(...\) -a \(...\)]
特殊条件测试
:表示不作任何事情,其退出值为0
true 表示总为真,其退出值为0
false 表示总为假,其退出值为255
3)case语句
case 字符串 in
模式1) ...;;
模式2)...;;
...
esac
每个模式字符串的最后一条命令必须以;;结束。
模式字符串可以使用通配符
如果一个模式字符串中包含多个模式,那么各模式之间应以|分开
各模式字符串应该是唯一的,不应该重复出现
用esac结束case语句
case语句的退出值是整个结构中最后执行的那个命令的退出值
4)while语句
while 测试条件(可为命令表,其值为最后一个命令的退出值)
do
done
5)until语句
until 测试条件
do
done
6)for语句
for 变量 [in 值表(可为正则表达式,也可为位置参数$*,此时$*可省略不写)]
do
done
也可以用算术表达式方式
((e1;e2;e3))
7)break ,continue命令
break命令可以是我们从循环体中跳出来,格式:
break [n] n表示要跳出几层循环
8)exit命令
exit [n]
9)select语句
通常用于菜单的设计,它自动完成接收用户输入的整个过程,包括显示一组菜单项及读入用户的选择。
select identifier [in word...]
do
done
如果 in word 这一部分被省略,那么参数identifier就以位置参数作为给定的值。
10、函数
shell脚本与函数间的参数传递可利用位置参数和变量直接传递。函数中所用的位置参数$1,$2对应于函数调用语句中的实参。
11、作业控制
set命令的monitor选项被打开,即执行命令set -o monitor,则交互式shell就实施作业管理。
1)jobs
2)kill
kill -9 PID
3)bg ,fg
bg命令可以把前台作业切换成后台作业。fg命令可以把后台作业切换成前台作业。
12、shell内置命令
1)eval命令
eval [arg...]
可以利用别的命令行作为自己的参数,进行相应的变量或命令替换,并把替换结果结合成一个新的命令行,然后读取加以执行。
2)exec命令
exec [arg...]
它在本shell中执行由参数arg指定的命令,并不创建新进程
3)hash命令
4)readonly命令
5)trap命令
6)type命令
7)unset命令
8)umask命令
9)wait命令