01、为什么叫Shell? Command Interpreter,交互的命令解释器,它是相对于kernel的说法,是kernel的外壳程序,用来实现用户与kernel的命令行沟通:将用户的命令翻译给内核处理,同时将内核的处理结果反馈给用户。 系统登陆时取得的shell称之为login shell或primary shell。 在shell中所下达的命令,都是shell所fork出产生的子进程。 在shell中执行的脚本,则是另外由一个单独的非交互的sub-shell取执行,然后在由sub shell执行script中的各命令(也会产生相应的进程) Linux OS支持多种shell,具体在/etc/shells中可以看到,主要分为sh(如sh、bash)和csh(csh、tcsh、ksh)两大类。 02、Shell prompt(PS1)与Carrige Return(CR)的关系 PS1是用来告诉用户可以输入了,通常有两种形式: $:给普通用户使用 #:超级用户使用 CR由Enter回车键产生,是让用户告诉shell,我的命令输入完成,shell可以去解释和执行了。 命令行的定义:位于shell prompt和CR字符之间用户输入的文字。 一个标准的命令行由三部分组成,其中后面两个部分是可选的。 command-name options arguments 重要原理 Shell会根据IFS(Internal Field Separator)将命令行拆解为字段(word),然后再处理各字段中的特殊字符(meta),最后再重组命令行。 常见的IFS有:空格键、制表符、回车键等。 命令的名字可以来源于: Shell内建命令 $PATH之下的外部命令 命令别名 指定路径的其他外部命令或脚本 03、echo命令 echo的作用:将其argument送至标准输出。默认在显示完输入参数之后,再补充送出一个换行符(new-line character)。如要取消该换行符,采用echo -n arguments即可。 所以,直接输入一个不带任何选项和参数的echo命令,将输出一个空白行(就是new-line character)。 $echo $ 而输入echo -n相当于完成echo输入,再回车到另一行,echo执行将无任何输出。 $echo -n $ echo命令的三个选项: -e:启用对反斜杠转义字符的识别 -E:关闭反斜杠转义字符(默认为关闭) -n:取消行尾的换行符 所以echo常用来检查变量值 04、引用和meta处理(单引号、双引号、反斜杠) 4.1 Shell中的字符类型 命令行中的每一个字符,要么是literal character,要么是meta character。前者就是普通字符,后面是具有特别功能和意义的特殊字符(保留字符)。例如,IFS和CR都是meta。其他常用的meta还有: =:设置变量 $:用来对变量或运算进行替换 >:重定向stdout <:重定向stdin |:管道 &:重定向文件描述符,或将命令置于后台运行 ():将内部的命令置于nested-subshell中运行,或用于整数运算、命令替换。 {}:将内部的命令置于non-named function中运行,或用于变量替换的边界范围界定。 ;:执行前一个命令结束后,不判断返回值,继续执行分号后的下一个命令。 &&:判断前一个命令返回值是否为true,如实则继续执行下一命令。 ||:判断前一个命令返回值是否为false,如实则继续执行下一命令。 !:执行history中的命令。 其他…… 这些特殊字符由于具有特别的含义和功能,如不该出现的时候却使用了会导致命令出错或者达不到预期的效果。因此,在大部分情况下,我们根据需要会选择性的通过quoting来关闭这些meta。 escape:逃脱符。仅关闭其后紧接的单一meta。 soft quote:双引号。部分关闭内部的meta,如$、``和\这三种则不被关闭。 hard quote:单引号。全部关闭内部的meta字符。 空格键在单引号和双引号内均会被关闭 单引号、双引号在soft quote和hard quote中均被关闭 ENTER键在这三种引用内均被关闭,视为换行符,但是在命令重组阶段分别被视作换行符、空格符或无字符。 4.2 区分shell meta和command meta $awk {print $0} 1.txt #语法错误:{}在命令行中被视作命令块用,而括号中的命令又没加上;分号 $awk '{print $0}' 1.txt #OK:用''关闭所有大括号meta,使其成为awk的参数,避免在shell中处理 $awk "{print \$0}" 1.txt #OK:由于$在""未被关闭,所以需加用\来关闭 $awk \{print\ \$0\} 1.txt #OK:没有使用''和"",全部使用\来关闭shell meta $awk "{print $0}" 1.txt #语法不报错:""不能关闭$,所以$0还是shell变量,$0不能成为awk的Field Number。因为此处不是在执行脚本,所以$0也没有意义,被当作0处理,因此逐行打印0。 $awk "{print $1}" 1.txt #语法不报错:""不能关闭$,所以$0还是shell变量,$0不能成为awk的Field Number。因为此处不是在执行的脚本内部,所以$1也没有意义,被视为空值。 $awk "{print $10}" 1.txt #语法不报错:""不能关闭$,所以$0还是shell变量,$0不能成为awk的Field Number。因为此处不是在执行的脚本内部,所以$1也没有意义,被视为空值。因为位置参数最大是$9,又没有采用边界界定符,所有$10被视作$1和0,而$1被无视,所以等价于逐行打印0。 上述第一行,由于{}在shell中是用来将其中的命令组合起来成为一个命令块,那么{print $0}被视作为一命令块,其语法要求最后一个命令后面要用分号。所以上述写法会报语法错误! 上述第二行,用hard quote关闭了{}的命令块功能,同时也关闭了空格和\$0在shell中的meta作用,从而不被Shell作为Shell meta先解析,使得这几个meta成为命令awk自身的command meta($0是awk的field number,表示整行内容),而作为命令行参数的内容去解析。 使用第三行和第四行也同样达到取消{}、空格和$作为shell command的效果。其他: 发现在shell中任意命令(非执行script)末尾输入\$1-\$9,\$1-\$9会被无视、语法不报错。 在shell中任意命令(非执行script)末尾输入\$0,结果有所不同、语法不报错。 假设awk使用的$x的值从shell中获取进来,可采用变量替换来做(不要直接用hard quote,因为hard quote关闭了所有shell meta,无法直接进行变量替换),采用下述方法: $A=0 $awk "{print \$$A}" 1.txt $awk \{print\ \$$A\} 1.txt $awk '{print $'$A'}' 1.txt $awk '{print $'"$A"'}' 1.txt 05、变量与export 5.1. 定义变量(set,=) 设定变量采用 变量名=变量值 的格式,注意: =前后不能有IFS,=后面可以为null 变量名是 Case Sensitive(大小写敏感的) 变量名避免使用meta、$ 变量名第一个字符不能是数字 变量名长度限制在256个字符 首次set变量可以理解为定义变量并对其赋值 之后每次对变量名执行=,相当于对变量重新赋值 已经赋值的变量已存在,这对变量做进阶处理时${var}有影响 5.2. 替换变量(符号$) Shell强大的原因就是因为在命令行中其支持替换(变量替换、命令替换),变量替换的格式: $符号加上变量名,如$A,A必须已定义。 注意: 变量替换是指用变量的值来替换$变量名,将其再放置到command line之中; 不要用数学逻辑来套用变量设定,变量的值只看变量每次被set时=后面的值,与其他无动态关联关系,如: A=B B=C 这里,A的值不会变成C A=B B=$A A=C 这里,A的值最终为C,B是一个变量,值为C,也不会让B的值等于C 利用命令行的变量替换和区隔符号:可以append变量的值: A=B:C:D A=$A:E 而不能采用: A=BCD #A的值D A=$AE #此处,AE被视作一个变量,而不是先$A,再扩充E。若AE未定义,那么$AE为空,使得A为空值。 而应采用: A=BCD A=${A}E #使用{}限定变量名的范围,A变为BCDE 注:${}有很多用法 5.3. 设定环境变量(export) 环境变量即为全局起作用的变量,在shell上定义的变量均属于local variable,只有通过export输出之后才能成为环境变量,供后续其他命令使用。但是也仅仅是对当前Shell的session起作用。语法: A=B #先定义 export A #变量A不需要带$,或者直接 export A=B 例如,下面使用了$A,会进行变量替换 A=B B=C export $A #$A替换为B,那么等价于export B,是将变量B输出为环境变量 另外,直接使用export命令可以查看已经设定的环境变量 export export环境变量的生存期: 在shell中export的环境变量仅对当前shell的session起作用(写在内存中),shell退出后不再起作用 source(点命令)配置文件可以使得配置文件中的设定在当前shell中立即生效(当前不用重启) 如要使得变量任何时候对各session均有效的环境变量,需将其写入/etc/profile(全部用户)或者.bashrc(当前用户)等配置文件中(source或重启之后永久生效) 5.4. 取消变量(unset) 取消变量等价于删除变量,该变量将未定义、不存在。但以下在shell中输出均一样。 $ A= $ echo $A $ $ unset A $ echo $A # $ 但是null value的变量和unset的变量在变量的进阶处理${var}中有很大的区别,例如 $ str= #null value $ var=${str=expr} #变量str已set为null,str在此不再被set赋值,set不执行 $ echo $var $ $ echo $str…

2018年05月23日 0Comments 1361Browse 4Like Read more

command substitution, Bash Shell command process flow, soft quotation。命令替换、双引号引用,Bash命令行执行流程

2018年05月22日 0Comments 1470Browse 3Like Read more