一、shell简介
shell的作用是解释执行用户的命令,用户输入一条命令,shell就解释一行【交互式】。另一种执行命令的方式是【批处理】,用户事先写一个shell脚本,其中有很多条命令,shell一次把这些命令执行完。shell程序从脚本中一行一行读取并执行这些命令,相当于一个用户把脚本中的命令一行一行敲到shell提示符下执行。shell脚本是解释执行的,不需要编译。
1、什么是shell执行脚本
脚本的后缀一般为.sh
脚本一般由#!开头,称作“shebang”,后面跟的是解释器
脚本注释时为 # 开头
执行时需要更改权限:chmod +x
*其实脚本就是一个文件,可以执行多行命令的文件。
shell脚本的第一行千万不要写错:#!/bin/bash.
2、shell脚本的执行过程
shell会fork一个子进程并调用exec执行./test.sh这个程序,exec系统调用把子进程的代码替换成shell脚本程序的代码段,并从它的_start开始执行。但是这个脚本.sh文件是个脚本文件,根本没有代码段和_start函数。所以exec会执行另一种机制。
由于第一行用shebang指定了解释器,则用解释器程序代码替换当前进程,并且从解释器的_start开始,这个文本文件被当做命令行参数传给解释器。
*解释型语言只需要解释器解释,不需要编译器,如shell脚本语言;C语言是编译型语言
二、shell变量
1、环境变量
环境变量可以从父进程传给子进程,所以shell进程的环境变量可以从当前的shell进程传给fork出来的子进程,用printenv可以显示当前shell进程的环境变量。
*fork函数得到的子进程从父进程继承了整个进程的地址空间,包括:进程上下文、进程堆栈、内存信息、打开的文件描述符、信号控制设置、进程优先级、进程组号、当前工作目录、根目录。资源限制、控制终端、环境变量等。但是父进程设置的锁子进程不继承且子进程的未决信号集被设置为空集。
2、本地变量
只存在当前shell进程,用set命令可以显示当前shell进程中定义的所有变量,包括本地和环境变量。
当定义环境变量时,等号的两边不能有空格,否则会被shell解释为命令和命令行参数。一个变量定义后进存在当前shell进程,是本地变量,用export可以把本地变量导出为环境变量。
用unset可以删除已定义的环境变量
VARNAME=value #定义本地变量
export VARNAME=value #导出本地变量,也可以写为VARNAME=value;
export VARNAME
unset VARNAME #删除已定义的环境变量或本地变量
3、变量引用
如果一个变量叫做VARNAME,用${VARNAME}可以表示它的值,在不引起歧义的情况下也
可以 用$VARNAME表示它的值。通过以下例子比较这两种表示法的不同:
echo $SHELL
echo $SHELLabc
对比:
echo ${SHELL}
echo ${SHELL}abc
注意,在定义变量时不用$,取变量值时要用$。和C语言不同的是,Shell变量不需要明确定义类型,事实上Shell变量的值都是字符串,比如我们定义VAR=45,其实VAR的值是字符串45而非整数。Shell变量不需要先定义后使用,如果对一个没有定义的变量取值,则值为空字符串。
三、替换
1、文件名代换
这些用于匹配的字符称为通配符(Wildcard),具体如下:
通配符 * : 匹配0个或多个任意字符
? : 匹配一个任意字符
[若干字符] : 匹配方括号中任意一个字符的一次出现
$ ls /dev/ttyS*
$ ls ch0?.doc
$ ls ch0[0-2].doc
$ ls ch[012][0-9].doc
注意,Globbing所匹配的文件名是由Shell展开的,也就是说在参数还没传给程序之前已经展开了, 比如上述ls ch0[012].doc命令,如果当前目录下有ch00.doc和ch02.doc,则传给ls命令的参数实际上是这两个文件名,而不是一个匹配字符串。
2.命令行代换
由反引号括起来的也是一条命令,Shell先执行该命令,然后将输出结果立刻代换到当前命令行中。
$ DATE=`date`
$ echo $DATE
例如定义一个变量存放date命令的输出:
命令代换也可以用$()表示: $ DATE=$(date)
算术代换:$(())
用于算术计算,$(())中的Shell变量取值将转换成整数,例如:
$ VAR=45
$ echo $(($VAR+3))
$(())中只能用+-*/和()运算符,并且只能做整数运算。
四、转义字符\
\反斜杠被用作转义字符,用于去除紧跟其后的单个字符的特殊意义。
例:
touch $ $ #创建一个名为 $的文件
touch \$\ \$ #创建一个名为 $ $的文件(中间有空格)
还有一个字符虽然不具有特殊含义,但是要用它做文件名也很麻烦,就是-号。如果要创建一个文件名以-号开头的文件,这样是不行的: 即使加上\转义也还是报错: 因为各种UNIX命令都把-号开头的命令行参数当作命令的选项,而不会当作文件名。如果非要处理 以-号开头的文件名,可以有两种办法:
touch ./-hello #前面加上当前路径
touch -- -file #前面加上两个--
五、单引号和双引号
1、单引号
和C语言不一样,Shell脚本中的单引号和双引号一样都是字符串的界定符,而不是字符的界定符。单引号用于保持引号内所有字符的字面值,即使引号内的\和回车也不例外, 但是字符串中不能出现单引号。如果引号没有配对就输入回车,Shell会给出续行提示符,要求用户把引号配上对。
2、双引号
双引号用于保持引号内所有字符的字面值(回车也不例外),但以下情况除外:
$加变量名可以取变量的值
反引号仍表示命令替换
\$表示$的字面值
\`表示`的字面值
\"表示"的字面值
\\表示\的字面值 除以上情况之外,在其它字符前面的\无特殊含义,只表示字面值
原文地址:http://zhaoxiaohu.blog.51cto.com/10778115/1972926