shell脚本编程诀窍--适用于linux,bash等 所学技术总结

看过不多的几本shell编程和linux命令方面的书,这一本给我的印象尤为深刻,虽然仍然是入门书籍,但是觉得比以前看的要更细,更广一点。今天刚看完,也是今天才开始决定开博客的 ,就以这本书中内容中技术上的总结,作为我第一篇技术博客好了。


启动交互式shell  首先会读取/etc/profile  ~/.profile ~/.bashrc /etc/bashrc

less   选项 -X  可以防止屏幕刷新,用less前终端显示的内容也不会丢失,这个好像是控制台的默认模式。


alias 别名   用unalias 可以取消,   别名在需要重复键入复杂值的时候最为有用,还有就是rm 等危险操作  加入-i选项,防止误操作    指令前添加\可以不使用别名


history  首先当前shell的命令在退出登录前都只会存储在内存里,用history命令调用,不在.bash_history文件里面    

HISTSIZE定义最多存储命令数,

HISFILESIZE定义最大历史文件大小,

HISTCONTROL定义忽略前导空格,

HISTINGORE定义不需要存储的命令 ,其中ignoredups忽略重复行,ignorespace忽略有前导空格的行,ignoreboth忽略两者 

HISTFILE定义历史文件 


shell 所有参数$* $@ 后者为分开的 ,切记使用时加上双引号,不然读入的参数仍然是以空格为分隔传给变量的;  $#为参数的总个数

  

关于shell中调用函数,函数的返回值 有两种传递方式,

1 通过exit return  这样 在调用之后立刻用$? 这个值可以获得传出的值

2 通过 a=function 将函数执行得到的 所有echo产生的结果赋值给a,同时$?可以获得成功函数与否,0成功 1 失败


shopt 命令用于管理bash的各种选项 主管BASHOPOTS

set  命令用于管理SHELLOPTS  前者主要针对bash  而这个针对的是shell环境   set 中以‘-’号开启功能 ‘+’号取消功能 


其中pipefail开启后  使用管道命令时退出码在管道的任一阶段失败后都会返回非0

同样 使用PIPESTATUS数组也可以 不过要一次性记录数组所有值,不然值会被接下来的任意命令的结果覆盖,从管道最右边开始是0


BASH_COMMAND 显示当前正在运行的命令,在中断时比较有用


有4个有用的数组变量我记着,FUNCNAME用于显示当前正在运行的函数名,从0开始往上回溯调用者

BASH_SOURCE显示正在运行的脚本名 ,也是往上回溯

LINENO显示在当前脚本中的行数

BASH_LINENO[i] 表示源文件中调用FUNCNAME[i] 所使用的行号 所以在被调用者中只要用BASH_LINENO[0]就可以表示调用者中的行数了

 

BASH_VERSION 用于记录bash版本名称

PWD 为pwd命令结果  而  OLDPWD 为前一个目录  可用`cd -`命令返回


TIMEFORMAT 用于控制time命令输出的格式,可以用来检测进程运行时间time -p commmand, 分为总时间,用户空间 系统空间时间


PPID为调用者的pid   而 $$显示当前进程的pid

RANDOM为0到32767之间的随机数,

SECONDS会每秒加一 默认是当前shell登陆的时间

REPLAY为默认输入,一般是上一次的输入

BASH_XTRACED 这个变量 当set -x 设置时  会把set -x 的输出 输出到变量指定的文件描述符中去 ? 待实验 一定要是文件描述符吗


GLOBIGNORE 变量用于让*通配符 忽略某些匹配模式的结果,用冒号隔开

IFS 是bash 用户分隔输入的 字符  空格 制表符 还有换行符

TMOUT 和read -t 同样用于超时 设置 还有 timeout命令


shell匹配的  用*匹配0到无穷个  ?匹配1个必须一个, 还有{}大括号可以放入所有可选的项目,用逗号分隔

开启shopt -s  dotglob 可以匹配到点开头的文件  . 和.. 除外

nullglob 可以让通配符匹配不到的时候 不把通配符本身当成匹配项目

extglob  可以扩展匹配  比如 ?(models)匹配任意一个  +()匹配一到多个  *()匹配0到多

@()匹配一个   !()匹配除一个以外的


几种可用类 这里记一下 [a-z] 相当于 [[:alpha::] [[:alnum:]] [[:blank:]]空格制表符     [[:cntrl:]]非打印控制字符   [[:dight:]] [[:graph:]]字母数字标点 [[:lower:]] [[:upper:]] [[:print:]]可打印字符 [[:punct:]] [[:space:]]空白字符  [[:xdigit:]]


shell中单引号中所有字符都不会被解释  双引号中除$引用变量以外也不会被解释

特殊字符如 分号  感叹号(历史命令) &符号 各种括号等 可用反斜杠转义


test 与 []命令效果是一样的, 其中]是[的参数 没有也不要紧的  有-O -G是否属于当前用户 和组 -U 上次访问后是否修改过  


使用 [[ args =~ 正则表达式 ]] 可以带入正则表达式 用右边匹配左边的形式  可以用 (.+) (.*) (.@)等  表示有1个及以上 0到多个   1个字符   匹配后 利用BASH_REMATCH数组可以取出各个匹配项目


case  语句一共有3种结句方式 ;;  这个最普通 ,就是C语言switch里的break的意思。  

;;&  这个表示还要接下去匹配工作   

;&   这个表示接下来的一项也当做匹配上了,然后结束


循环  最后可以用 < 符号  将所要的内容从文件中输入

for循环 有  for a in b  和 for (( ; ; ))  这种C语言方式 这两种

continue 和break 后面跟数字可以指定跳出几重循环 很方便

select a in b  中,会自动生成菜单 利用PS3变量作为提示符, 用户输入的数字为REPLY变量,而a为输入的数字所对应的项目名称    select生成的菜单只能用中断的方法退出  他是无限循环的


变量的数字运算  可是使用  let命令  expr 命令  还有 (( ))括号进行 其中 第三种要得到求出的值的话,需要在前面加上$,优点是内部计算时不用在变量里面加$符号

变量长度是 ${#para}  的值


裁剪变量: ${para:pos:num}  变量 从pos位置(从0开始计数)开始的前num个字符被裁剪然后显示,其中num字段和前面的冒号可以省略  如果要从末尾开始计算裁剪位置 就使用: -pos  记住符号和冒号之间要有一个空格

还有一种模式匹配裁剪   利用{para#mod} {para##mod} {para%mod} {para%%mod}  两个符号的是贪婪匹配 总是匹配最长的一段,一个符号则匹配最短的一段,#是从开头 %是从结尾, mod区域使用bash的匹配和通配模式

{para^character}符号可以改成^^ , ,, 共4种 分别表示将para中对应字母改成大写或小写, 双个字符表示全部改 单个的话只匹配变量开头的那一个字符而已 不管匹配不匹配上。


变量查找替换   ${var//a/b}  在var中把a替换成b,那个双斜杠表示全部替换,如果换成单斜杠就只替换第一个 如果要替换开头的字符 用的 不是 ^字符 而是用#字符放在开头 而%表示结尾 通配符也可以使用  ;  如果要删除的话/b部分省略就行了


提供默认值  ${a:-b}  若a不存在或为空 则用b   {a:=b}  同前  单a会被赋值b  

[a?b] 有值时 即使为空 也是a  否则b   [a+b]  有值为b  没值为a

$[!var] 为2次取值, 会先引用$var   在将其值进行引用


getopts 能处理简单的命令行参数,将参数 选项分离存放 格式 getopts optstring name  其中 optstring 中指定选项以及是否要参数 后加冒号, name中存放当前选项,OPTARG中存放当前选项的参数 ,OPTIND 中存放下一个将要查询到的选项的 位置的索引 从1开始的


数组可以一次性赋值 可以稀疏赋值(不按照序号连续赋值 ),有了值后 可以再增加a=( ${a[@] b} 即可 或者应用 ${#a[@]}表示数组元素总数 或者减少 用unset即可  直接unset 数组名则是取消整个数组,    

数组赋值的输入的话 不一定是以空格为间隔的 这个只要修改IFS就可以了  注意先保存一下       或者  可以把IFS的修改和指令运行放在同一行 这样IFS修改有效性就只有这一行了。

如果用IFS 和 read -a 读入数组相组合的话,同一行的输入会被分隔符分成多份放在数组的每一项里面

利用变量裁剪的方法 也可以裁剪数组总元素


关联数组 可以使用字符串作为数组索引  还有  可以反向查找  for b in ${!a[@]} ,此时b的值时索引的值  a[b]得到的是数组里的对应结果  

可以在一个数组中添加另一个数组  利用 a+=( “${b[@]}” ) 即可


nohup 用于后台运行 终端关闭也无妨

wait 可以选择要等待结束的 进程 (必须是当前进程的子进程  不然直接返回)


交互式登录shell  /etc/profile  ~/.profile ~/.bashrc /etc/bashrc

交互式非登录shell  在shell里键入shell时读入  ~/.bashrc /etc/bashrc

非交互式shell   常用于脚本中 读取BASH_ENV变量 没有则不读取


使用history命令的!可以调出使用过的命令 后面加数字  或者命令的前几个字母都可以


使用stat命令可以获得一个文件的权限的具体信息  可以模拟ls  命令较有用

cat命令可以标记行号,非空行 保留单个空白行 , 显示非打印字符-v 等

maktemp命令可以制造零时文件名,可以用X指定随机生成的字母的个数


重定向的<<符号 后面如果用<<-的话 之后输入的每行文字全部忽略前导空格,这有助于代码的层次清晰


使用join组合两个文件时,可以选择按字段组合  选择显示全部内容等


cut命令中的 -t 如果指定空格 则只能识别一个空格 如果每行里面的空格数不一样,会导致域选择的错误


shuf 指令用于随机排列指定序列, 可以是直接在参数里指定,利用-e  或者 指定文件 ,文件里每行写好要随机的字符, 或者可以用-i 来使用 1-6这样的形式


paste 也是把两个文件放在一起 默认会全部贴起来,不一样的部分也不管,就是单纯的把相对应的行号相同的行贴在一起,可以用-d指定分隔符,可以指定多个,放在不同的两列之间


pr 可以按照指定每行多少个进行打印,使用-T可以去掉格式的表头


printf指令同C语言一样指定格式字符串


tr命令使用[] 可以把需要匹配的字符包括进去,或者用[:alpha:]这样的等等


uniq 命令-w -s 可以指定输出或者忽略前面n个字符, 使用-u -d 可以指定输出非重复行 或 重复行 使用-f则可以指定比较时要忽略前面的几个字段 ,字段用空格 制表符隔开


factor命令用于输出指定数字的素数


id groups  getent其中第三个用于获取指定数据库里的指定信息

md5sum用于计算校验值,如果加入-c  则对于计算过值并排放好的文本可以用来检验校验值 ,当然要放在同一目录底下


mkfifo用于制造管道文件,不过管道必须双向打开不然无法正常工作,


seq 用于 输出一个序列, 可以用seq a b c  中的b来指定步长


timeout则用于制造时间限制,timeout -s signal (time)   指定经过time秒后发送signal信号给程序


xargs 用于将参数传给指定的命令 可以选择一次传几个,

yes 用于将一个值不断的重复输出  用于需要不断回答的地方


暂且总结了这么多  比较乱  算是给自己的一个复习的参考  今后不断巩固完善









郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。