zzgzyyz 发表于 2018-8-27 10:43:10

shell脚本基础入门(二)

  以下为本教程的《入门篇》,适于初学者快速入门以及老手查缺补漏。
  第一招 HelloWorld
  第一式:echo
  echo "Hello World"
  echo -n "Hello World" # 不带换行
  echo -e '\e[0;33;1mHello\e[0m World' # 带颜色的玩法
  echo -e '\e[0;33;4mHello\e[0m World' # 带颜色+下划线
  echo -e '\e[0;33;5mHello\e[0m World' # 带颜色+闪烁
  格式为 \e[背景色;前景色;高亮格式m,请阅读详细文档后使用正确的姿势进行装逼。
  第二招 判断
  第一式:if
  if true
  then
  echo "Hello World"
  else
  echo "Bug"
  fi
  if false
  then
  echo "Hello World"
  elif true
  then
  echo "Bug"
  else
  echo "Bee"
  fi
  判断原理
  if、elif会执行它后面跟着的命令,然后看返回值是否为0,如果为0则执行then下面的语句块,
  否则执行else下面的语句块。
  $ true
  $ echo $?
  0
  $ false
  $ echo $?
  1
  注:
  1.true、false事实上也为一个命令,true的返回码必为0,false的返回码必为1
  2.$?为shell内置变量,用于存放上一个命令的返回码
  第二式:test、[ ] 和 ` `
  test、[ ]、` `实际上都是shell中的命令,执行之后会返回1或0,而这几个命令与if相结合可以达到我们所
  需要的许多判断功能,例如测试字符串是否为空的三种写法:
  s=""
  if [ -z ${s} ]
  then
  echo "empty"
  fi
  if [[ -z ${s} ]]
  then
  echo "empty"
  fi
  if test -z ${s}
  then
  echo "empty"
  fi
  事实上,if后的[ ]、` `、test命令都是可以单独执行的,而根据if的判断原理,后续执行哪个分支也是由
  [ ]、` `、test的返回值来决定的,以下是单独执行它们的效果:
  $ s=""
  $ [ -z "${s}" ]
  $ echo $?
  0
  $ s="abc"
  $ test -z "${s}"
  $ echo $?
  1
  $ s="123"
  $ [[ 100 -lt ${s} ]]
  $ echo $?
  0
  在性能方面[ ]和test性能基本相同,` `性能是最高的,为前两者的5倍左右(以-d运算符测试),所以建议
  尽量使用` `提高脚本性能。
  文件测试
  以下为本教程的《入门篇》,适于初学者快速入门以及老手查缺补漏。
  第一招 HelloWorld
  第一式:echo
  echo "Hello World"
  echo -n "Hello World" # 不带换行
  echo -e '\e[0;33;1mHello\e[0m World' # 带颜色的玩法
  echo -e '\e[0;33;4mHello\e[0m World' # 带颜色+下划线
  echo -e '\e[0;33;5mHello\e[0m World' # 带颜色+闪烁
  格式为 \e[背景色;前景色;高亮格式m,请阅读详细文档后使用正确的姿势进行装逼。
  第二招 判断
  第一式:if
  if true
  then
  echo "Hello World"
  else
  echo "Bug"
  fi
  if false
  then
  echo "Hello World"
  elif true
  then
  echo "Bug"
  else
  echo "Bee"
  fi
  判断原理
  if、elif会执行它后面跟着的命令,然后看返回值是否为0,如果为0则执行then下面的语句块,
  否则执行else下面的语句块。
  $ true
  $ echo $?
  0
  $ false
  $ echo $?
  1
  注:
  1.true、false事实上也为一个命令,true的返回码必为0,false的返回码必为1
  2.$?为shell内置变量,用于存放上一个命令的返回码
  第二式:test、[ ] 和 ` `
  test、[ ]、` `实际上都是shell中的命令,执行之后会返回1或0,而这几个命令与if相结合可以达到我们所
  需要的许多判断功能,例如测试字符串是否为空的三种写法:
  s=""
  if [ -z ${s} ]
  then
  echo "empty"
  fi
  if [[ -z ${s} ]]
  then
  echo "empty"
  fi
  if test -z ${s}
  then
  echo "empty"
  fi
  事实上,if后的[ ]、` `、test命令都是可以单独执行的,而根据if的判断原理,后续执行哪个分支也是由
  [ ]、` `、test的返回值来决定的,以下是单独执行它们的效果:
  $ s=""
  $ [ -z "${s}" ]
  $ echo $?
  0
  $ s="abc"
  $ test -z "${s}"
  $ echo $?
  1
  $ s="123"
  $ [[ 100 -lt ${s} ]]
  $ echo $?
  0
  在性能方面[ ]和test性能基本相同,` `性能是最高的,为前两者的5倍左右(以-d运算符测试),所以建议
  尽量使用` `提高脚本性能。
  文件测试:
http://blog.51cto.com/e/u261/themes/default/images/spacer.gif
  字符串比较:
http://blog.51cto.com/e/u261/themes/default/images/spacer.gif
  注意: 1.在字符串两边加上""防止出错;
  2.是字符串比较,不要错用成整数比较;
  3.如果是在[ ]中使用,需要将它们写成\。
  整数比较:
http://blog.51cto.com/e/u261/themes/default/images/spacer.gif
  第三式:&&、||:
http://blog.51cto.com/e/u261/themes/default/images/spacer.gif
  注:只有` `才允许把&&写在里面
  |\|\|可以用来对两个判断语句求或| |---| |if [ -n "abc" ] \|\| [ -n "aa" ]| |if [[ -n "abc" ]] \|\| [[ -n "aa" ]]| |if test -n "abc" \|\| test -n "aa"| |if [[ -n "abc" \|\| -n "aa" ]]|
  注:只有` `才允许把||写在里面
  小技巧
  &&、||还可以用来拼接命令,达到按前一个命令成功与否来决定是否执行后一个命令的效果
  cd /data && ls # 当`cd /data`返回0(即成功)时才执行后面的`ls` cd /data || cd /root # 当`cd /data`返回非0(即失败)时才执行后面的`cd /root`
  第三招:循环
  第一式:for
  for i in {1..100}
  do
  echo ${i}
  done
  注:
  1.{1..100}属于通配的一种写法,展开会是1 2 3 ... 100(1~100以空格隔开)这样的字串。
  2.例如for i in 1 2 3;这样的语句,for会将1、2、3依次赋值于i进行循环,而对于通配的情况,for则会将通配展开后将里面的每一项依次赋值于i进行循环。
  for i in `seq 100`
  do
  echo ${i}
  done
  for i in `seq 1 2 100`
  do
  echo ${i}
  done
  注:
  1.seq本身为一个命令,用于输出数字组成的序列,如seq 100会生成并输出1 2 3 ...100(1~100以换行符隔开)这样的序列,而seq 1 2 100则会生成并输出1 3 5 ...99(以1开始,2为公差的等差数列中小于100的项,以换行符隔开)。
  2.反引号(')之间的命令会被执行,其输出结果会转换成一个变量,故上面的for in会依次取出seq的执行结果赋值于i进行循环。
  for ((i = 0; i < 100; i++))
  do
  echo ${i}
  done
  for ((i = 0; i < 100; i+= 2))
  do
  echo ${i}
  done
  注:
  以上与C语言式的for循环语法基本相同,区别在于双重括号:(( ))
  第二式:while、until
  i=0
  while [[ ${i} -lt 100 ]]
  do
  echo ${i}
  ((i++))
  done
  i=0
  until [[ ${i} -ge 100 ]]
  do
  echo ${i}
  ((i++))
  done
  注:
  while和until的判断原理与if是类似的,它会执行并它后面跟着的命令,不同点在于:
  while是后面语句返回值为0,则执行循环中的语句块,否则跳出循环;
  until则是后面语句返回值非0,则执行循环中的语句块,否则跳出循环。
  第四招:变量
  第一式:整数
  整数的运算
  方法较多,此处只列举最浅显易懂,并且效率最高的办法——直接将符合C语言语法的表达式放到(( ))中即可达到对整数的计算目的:
  echo $(( 1+1 )) # 最简单的1+1
  echo $(( (1+2)*3/4 )) # 表达式中还可以带括号
  echo $(( 1 hello.txt # hello.txt原有的将被覆盖
  echo "Hello World" >> hello.txt # hello.txt原有内容后追加`Hello World`
  第二式:重定向标准错误流(stderr)
  把程序的错误信息输出到文件
  例如文件路径中不存在+++这个文件:
  # ls +++
  ls: cannot access +++: No such file or directory
  # ls +++ > out.txt
  ls: cannot access +++: No such file or directory
  上面的ls +++后输出的内容为标准错误流中的错误信息,所以即使用> out.txt重定向标准输入,错误信息仍然被打印到了屏幕。
  # 以下两种方式都会将`ls +++`输出的错误信息输出到`err.txt`(若不存在则创建)
  ls +++ 2> err.txt # err.txt原有内容将被覆盖
  ls +++ 2>> err.txt # err.txt原有内容后追加内容
  第三式:重定向标准输入流(stdin)
  1.让程序从文件读取输入
  以默认从标准输入读 取表达式,并进行数学计算的命令bc为例:
  # bc -q
  1+1
  2
  注:
  1.1+1为键盘输入的内容,2为bc命令打印的计算结果
  2.bc后的-q参数用于禁止输出欢迎信息
  3.以上重定向方法格式为命令< 文件路径
  如果我需要把已经存在文件exp.txt中的一个表达式输入到bc中进行计算,可以采用重定向标准输入流的方法:
  bc -q < exp.txt
  注:
  1.当exp.txt中内容为1+1时,以上语句输出2
  2.由于bc命令本身支持从文件输入,如不使用重定向,也可用bc exp.txt达到相同效果
  2.将变量中内容作为程序输入
  EXP="1+1"
  bc -q
页: [1]
查看完整版本: shell脚本基础入门(二)