纸水仙 发表于 2018-8-18 14:35:18

Shell 编程基础(一)

  Shell脚本的关键在于输入多个命令并处理每个命令的结果,甚至需要将一个命令的结果传给另一个命令。Shell可以让你将多个命令串起来,一次执行完成。
  基本格式:
  第一行必须为固定格式,指明脚本使用哪种shell来运行脚本,通常shell脚本中会以 # 作为注释,注释号后面的内容不会参与脚本的运行,但是,第一行是个例外。

  变量命名法则:
  1、不能使程序中的保留字:例如if, for
  2、只能使用数字、字母及下划线,且不能以数字开头,不能使用 - (减号)
  正确:_abc123 ;abc123 ; abc_123
  错误:var1-abc=100;var1-123=100;-var1=100
  3、见名知义
  name,date
  4、统一命名规则:驼峰命名法
  HostName
  直接运行脚本的时候,会新开一个shell进程,脚本中默认关闭了alias功能
  局部变量:生效范围为当前shell进程;对当前shell之外的其它shell进程,包括当前shell的子shell进程均无效。
  环境(全局)变量:生效范围为当前shell进程及其子进程
  本地变量:生效范围为当前shell进程中某代码片断,通常指函数
  位置变量:$1, $2,$N ...来表示,用于让脚本在脚本代码中调用通过命令行传递给它的参数
  特殊变量:
  $?
  返回上一条命令执行状态
  $0
  命令本身
  $*
  传递给脚本的所有参数,全部参数合为一个字符串,用双括号括起
  $@
  传递给脚本的所有参数,每个参数为独立字符串,每个都用双括号括起
  $#
  传递给脚本的参数的个数
  $_
  上个命令的最后一个参数
  $$
  显示当前进程号
  $PPID
  显示父进程号
  $!
  上一个子进程的进程号
  $-
  在Shell启动或使用set命令时提供选项
  $n
  位置参数值,n表示位置
  使用pstree -p 查看进程树
  $@ $* 只在被双引号包起来的时候才会有差异
  变量赋值:
  变量名=值
  赋值等号与值之间没有空格
  [中括号里写变量的时候,记得加双引号]
  (1) 可以是直接字串; 变量名=root
  如果值为带空格或特殊字符时,请使用双引号和\转义符号
  (2) 变量引用:   变量名="$USER"
  (3) 命令引用:    变量名=`指令`
  变量名=$(指令)
  变量引用:
  ${变量名}
  $变量名
  "双引号":弱引用,其中的变量引用会被替换为变量值
  '单引号':强引用,其中的变量引用不会被替换为变量值,而保持原字符串
  显示已定义的所有变量:
  set
  删除变量:
  unset 变量名
  只读变量:只能声明,但不能修改和删除
  声明只读变量:
  readonly 变量名
  declare -r 变量名
  查看只读变量:
  readonly –p
  位置变量:在脚本代码中调用通过命令行传递给脚本的参数
  set -- 清空所有位置变量
  进程使用退出状态来报告成功或失败
  一般来讲,
  0 代表成功,1-255代表失败
  以下表为在未自定义退出状态码(exit)时的常见,可以参考
  状态码
  描述
  0
  命令成功结束
  1
  一般性未知错误,可能是无效参数
  2
  不适合的shell命令
  126
  命令不可执行
  127
  没有找到命令
  128
  无效的退出参数
  128+x
  与Linux信号x相关的严重错误
  130
  通过Ctrl+C终止的命令
  255
  正常范围之外的退出状态码
  bash自定义退出状态码
  exit :自定义退出状态码
  脚本中一旦遇到exit命令,脚本会立即终止;终止退出状态取决于exit命令后面的数字
  如果未给脚本指定退出状态码,整个脚本的退出状态码取决于脚本中执行的最后一条命令的状态码
  退出状态可以使用变量作为值,退出状态码最大值为255,如果值超过255时,将会通过
  取模运算值/256 把状态码缩减到0~255整数值之间,比如:
  exit 300
  300/256 取模=44    400/256 取模=144
  bash自带脚本测试
  bash -n 语法检查
  bash -x脚本执行按步调试

  算术运算
  +
  两个整数相加
  %
  两整数相除,取余数
  -
  第一个数减去第二个数
  *
  两整数相乘
  \
  第一个整数除以第二个整数
  实现算术运算的方法:
  (1) let 变量名=算术表达式
  (2) var=$[算术表达式]
  sum=$
  sum=$[$uid10+$uid20]
  (3) var=$((算术表达式))
  sum=$((uid10+uid20))
  (4) declare –i 变量名 = 数值
  (5) echo ‘算术表达式’ | bc
  条件测试
  若真,则返回0
  若假,则返回1
  1. test 语句
  2. [空格 表达式 空格]
  推荐使用第2种方法,因为我们去看系统本身自带的脚本编写使用的正是这一类方法。
  第一个 [ 之后和第二个 ] 之前必须加上一个空格,否则会报错


  上面的中括号是错误的格式,会报以下的错误


  ++++++++++++我是华丽的分界线++++++++++++++++++++


  上面的中括号是错误的格式,会报以下的错误


  ++++++++++++我是华丽的分界线++++++++++++++++++++
  以下才是正确的格式


  可以判断4类条件
  a.数值测试b.字符串测试c.文件测试d.布尔逻辑组合测试条件
  以下逐个看
  a.数值测试
  可以用在数字和变量(变量值是数字)上
  -lt
  小于
  less than
  -eq
  等于 equal
  -gt
  大于
  great than
  -ne
  不等于
  not equal
  -ge
  大于等于
  great equal
  -le
  小于等于
  less equal
  注意,当碰到系统特殊符号的时候,记得 \ 转义




  但是涉及到浮点值的时候,数值测试会有一个限制 ,我们来看一个例子:


  变量$var1的值是浮点值,脚本对这个值进行了测试,显然这里就报错。因此,请记住
  bash shell只能处理整数(zshell能很好的解决这个问题),当然,如果这个值只是用来
  echo 输出是没问题的。




  因此,此时shell的退出状态码也是为非0值了,也就是执行了else 之后的语句。
  b.字符串测试
  相等比较
  在比较字符的相等性时,会将所有的标点和大小写情况都考虑在内的
  ==
  字符串是否相同
  -n 字符串
  字符串是否为非0
  !=
  字符串是否不同
  -z 字符串
  字符串是否为0
  <
  左边的ascii码是否小于右边的ascii码
  =~
  左侧字符串是否能够被
  右侧的表达式所匹配
  用于[[ 双中括号中 ]]
  >
  左边的ascii码是否大于右边的ascii码


  使用调试工具来直观的看出状态码与结果


  使用=或者==,或者&quot;&quot; 和&quot;空格&quot; 的结果都是一致的




  使用单引号也是一致的


  这里需要注意的是,当值中带有空格的时候,变量没有双引号引起来会是报错的


  当变量双引号引起来的时候,


  正确输出


  所以,在写 bash 脚本的时候,别偷懒,对于变量的引用最好都加上双引号!就变量引用上来说,虽然 zsh 在这点要强过 bash,但是处于兼容性的考虑,还是把双引号带上吧。
  字符的比较
  先来一个初学者常犯的错误


  乍一看,没问题啊


  可以当然我们使用ls查看当前目录的时候,发现$var2的值被重定向至以$var2的值,也就是abcdA的文件中了。这是一个不易觉察的严重问题。脚本把 > 解析成了重定向输出符号。同时,因为重定向成功,因此exit退出码为0,就会执行then语句了。
  因此,使用 双引号 引起来 或 \ 转义解决吧。


  这才是规范的脚本写法,别掉坑了哦~~


  这才是正确的输出结果


  字符串的大小写比较


  在Shell的比较测试中,大写字母是被认为是小于小写字母的。这一点与sort命令恰好相反,同样的字符串用sort排序时,小写字母先出现,这是由于各个命令使用的排序技术不同造成的。


  因此,总结为2句话:
  shell编程时,小写字母 >(大于) 大写字母
  sort排序时,小写字母>(优先) 大写字母
  如果出现以下大小写混合并相同的情况呢


  那么就从左边开始比,第一位a相同,那就比第一位,b > A根据以前的总结,结果就是
  $var1 > $var2,不信就以图验证下


  而sort命令则是以按小写字母>相同的大写字母排序的,注意哦~


  如果是把数值的比较用了字符串的比较,那么你会怀疑你的数学是体育老师教的吧


  数字越大就是大


  最后的总结,如果使用错了操作符,可能无法得到正确的结果。
  比较类型
  使用的操作符
  数值
  -lt; -gt; -le; -ge; -eg; -ne
  字符串
  =; !=; >;
  右位移
  |
  位布尔或
  &&
  逻辑和
  =~
  双中括号中后面跟
  扩展正则表达式
  ||
  逻辑或
  va1++(va1--)
  自身先和后面的运算式运算,表达式的结果跟自身没有任何关系,再自身+-1的值赋与以后使用。
  例子: a=5 b=2
  a++ +b=7   (a+b=7,此时a的值为6)
  上条表达式后的下一条表达式a的值已经变化了
  a+b=8
  ++id ( --id)
  例子: a=5 b=2
  ++a +b =8(a+1=6,6+b=8,此时a的值为6)
  上条表达式后的下一条表达式a的值已经变化了
  a+b=8
  自身先+-1,再和后面的运算式运算,表达式的结果跟自身没有任何关系,
  以后的值就是原先自身先+-1
  双括号范例

  双中括号范例,扩展正则表达式

  双中括号范例,扩展正则表达式



  如果写成双等号的话,双中括号会自动转化为带转义的写法

  注意红框的地方

  第一章节到此结束,本人水平有限,如有错漏地方,欢迎指正。

页: [1]
查看完整版本: Shell 编程基础(一)