一.shell的历史
shell的作用是解释执行用户的命令,用户输入一条命令,shell就解释执行一条,这种方式称为交互式。
用户还有一种执行命令的方式叫做批处理,用户事先写一个shell脚本,其中有很多条命令,让shell一次性把这些命令执行完,而不必一条一条的敲命令。
shell脚本和编程语言很相似,也有变量和流程控制语句,但是shell脚本是解释执行的,不需要进行编译,shell从脚本中一行一行读取并执行这些命令,相当于一个用户把脚本中的命令一行一行敲到shell提示符下执行。
二.shell的执行原理
由于历史原因。UNIX系统中有许多种shell,比如sh,csh,ksh,tcah,bash等。
对于当前的一个shell比如bash来讲,在执行命令的时候,它并不会亲身去执行命令,因为有可能这条命令是条恶意命令会造成意想不到的后果。因此它会创建出一个子进程,让子进程去执行这条shell命令,而此时这个子进程也相当于是一个bash,因此当它执行shell脚本中的一行一行命令的时候,也要再去创建一个子进程(可看作是子子进程)来执行shell脚本中的一行一行的命令。
三.shell执行脚本
在shell脚本中用#表示注释,相当于C语言中的//,但是如果#位于第一行开头,它表示该脚本使用后面指定的解释器/bin/sh解释执行.
(1)chmod u+x script.sh
因为shell脚本不需要编译,因此刚创建的shell脚本文件并没有可执行权限,要想执行它,就必须加上可执行权限。
(2)/bin/bash script.sh
(3)除上边两种方式外,还有以下几种:
四.shell变量
按照惯例,shell变量由全大写字母加下划线组成,有两种类型的shell变量:
(1)环境变量
环境变量可以从父进程传给子进程,因此shell进程的环境变量可以从当前shell进程传给fork出来的子进程。用printenv命令可以显示当前shell进程的环境变量。
只存在于当前shell进程,用set命令可以显示当前shell进程中定义的所有变量(包括本地变量和环境变量)和函数。
环境变量是任何进程都有的概念,而本地变量是shell进程特有的概念。
在shell中定义或者赋值一个变量:
VARNAME=value
注意:等号两边都不能有空格,否则会被shell解释成命令或者命令行参数。 一个变量定义后仅存在于当前shell进程,它是本地变量,用export命令可以把本地变量导出为环境变量,定义和导出环境变量通常可以一步完成: export VARNAME=value
也可以分两步完成: VARNAME=value
export VARNAME
用unset命令可以删除已经定义的本地变或环境变量:unset VARNAME
五.变量引用
如果一个变量叫做VARNAME,用${VARNAME}可以表示它的值,在不引起歧义的情况下也可以用$VARNAME来表示。通过以下的例子来比较两者的不同:
程序代码:
实现结果:
注意:在定义变量时不用$,在取变量值时需要用$。
和C语言不同的是,shell变量不需要明确指明其类型。事实上shell变量的值都是字符串,比如VAR=100,表明VAR的值是字符串100而不是整数100。shell变量不需要先定义后使用,如果对一个没有定义的变量取值,则值为空字符串。
六.反引号``和$()的区别与联系
(1)相同点:都是将括起来的命令执行完毕后交给相应的对象或者输出。
(2)不同点:首先列举一个简单的例子
通过上图我们可以得出:
1.反引号中\$并没有将$的特殊意义转换 ,反引号包含的内容仍然被解释为一个echo $VAL取到了VAL变量的值并输出。
2.$()则正好相反,$明显被\转义成了一个普通字符,所以并没有取到变量值,而是返回了字符串本身的意思,故而返回了$VAL。
这说明反引号``对反斜杠\有特殊的转化,从而使反斜杠起不到转义的作用 。我们 对以上程序做如下修改:
从而得出:
1.反引号本身就对反斜杠进行了转义,保留了其本身的意思,如果我们想着反引号中起到\的作用,就要使用\\。
2.$()则不需要考虑\的问题,与平常使用的一样。