shell脚本学习--符号

一、shell简单介绍
     shell的作用是解释执行用户的命令,用户输入一条命令,shell就解释一行【交互式】。另一种执行命令的方式是【批处理】,用户事先写一个shell脚本,其中有很多条命令,shell一次把这些命令执行完。shell程序从脚本中一行一行读取并执行这些命令,相当于一个用户把脚本中的命令一行一行敲到shell提示符下执行
     shell脚本是解释执行的,不需要编译。
     文件/etc/shells给出了所有shell
shell脚本学习--符号_第1张图片
1、shell执行脚本
  • 脚本的后缀一般为  .sh
  • 脚本一般由 #! 开头,称作“shebang”,后面跟的是解释器
  • 脚本注释时为  #  开头
  • 执行时需要更改权限:chmod +x
例:
shell脚本学习--符号_第2张图片
由上例可看到
  • 脚本文件可以一次执行多条命令。
  • cd .. 进入上级目录打印了上级目录的路径,但是并没有进入到上级目录下。(原因在下面)

     除chmod+x执行脚本外,还可以/bin/bash my_script.sh执行脚本
2、 脚本的执行过程
     shell会fork一个子进程并调用exec执行./my_script.sh这个程序,exec系统调用把子进程的代码替换成shell脚本程序的代码段,并从它的_start开始执行。但是这个脚本.sh文件是个脚本文件,根本没有代码段和_start函数。所以exec会执行另一种机制。
     由于 第一行用shebang指定了解释器,则用解释器程序代码替换当前进程,并且从解释器的_start开始,这个文本文件被当做命令行参数传给解释器
*解释型语言只需要解释器解释,不需要编译器,如shell脚本语言;C语言是编译型语言
在上面的例子中,cd.. 后仍在当前目录的原因:
  • 交互式shell(命令行)fork/exec一个子shell用于执行脚本,父进程让子进程去执行命令,父进程在后台等待子进程退出在返回前台。
  • 子进程读取脚本中的cd .. 命令,调用相应的函数执行内建命令,改变当前工作目录为上一级目录(子进程)
  • 子进程读取脚本中pwd命令,fork/exec这个程序,列出当前路径,子进程等待pwd终止
  • pwd终止后,子进程继续执行,读到脚本文件末尾终止。
  • 子进程终止后,bash继续执行,打印提示符等待用户输入

*若将命令行下输入的命令用()括号括起来,也会fork出一个子shell执行小括号中的命令,命令行一行中也可以输入由分号;隔开的多个命令。

     对于内建命令,在交互式shell下输入则可以由自己l执行,如在命令行下输入 cd .. 则进入上级目录。若识别不是内置命令,则派生子进程,子进程exec,父进程得到结果。
     若想让内建的命令不创建子shell,直接在交互式shell下逐行执行脚本中命令:
  •      在执行./my_sscript.sh时,在前面加source:$source ./my_script.sh
  •      在执行./my_sscript.sh时,在前面加 . :$. ./my_script.sh

二、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、变量引用
     echo ${变量名}
     在不引起歧异的情况下也可以用 $变量名 来表示。
     如:
          echo $变量名aaa   #引起歧异,需要加上花括号
     shell变量不需要定义明确类型,因为shell变量都是字符串,对一个没有定义的变量取值则值为空字符串。
三、替换
1、文件名替换
1、通配符 * :匹配0个或任意多个字符
2、 ? :问好匹配一个任意字符
3、[] :方括号,匹配括号中任意一个字符的一次出现。
2、命令替换
1、$() :由括号括起来的也是一条命令,shell先执行括号内命令,然后输出结果立刻替换到当前命令行中。
2、'    :反引号同上。
 mytime=$(data +%y-%M-%d)          #或  mytime=$'data +%y-%M-%d)'
 echo $mytime
*$()和''的区别:
  • ''在执行时,shell不管''内是什么都先进行解释,然后把解释后的最终结果送给shell去执行,若解释后的最终结果不是shell可执行的命令时,则会出错,仅把单引号执行后的内容作为文本输出。
  • $()在执行时,若括号中是命令则直接丢给shell执行,若是变量取值,则仅做第一层的字面意思解释丢给shell执行。
  • ‘’产生的结果不会再给shel解释,而只作为赋值直接使用。$()在产生结果后还会进一步解释
          3、$(()):算数替换,用于算数计算,$(())中的shell变量取值将转换成整数
          $ VAR=45
          $ echo $((VAR+3))
          $(())中只能用加减乘除和()运算符,且只能做整数运算
shell脚本学习--符号_第3张图片

四、转义字符
     \反斜杠被用作转义字符,用于去除紧跟其后的单个字符的特殊意义。
例;
      touch $ $               #创建一个名为    $的文件
     touch \$\ \$           #创建一个名为     $ $的文件(中间有空格)
     
  对于-开头的文件,由于一般-开头的是命令行参数的选项,所以/也不能将其转义,若非要-开头,则:
     touch ./-hello     #前面加上当前路径
     touch -- -file      #前面加上两个-- 

五、符号
1、单引号和双引号
     在c中分别表示字符和字符串,在shell中均表示字符串,但是单引号对里面的内容直接输出,双引号允许替换。
     双引号中$加变量名可以取变量的值,\$表示$的字面值,\'表示 ' 的字面值,\\表示\的字面值


你可能感兴趣的:(shell,Linux)