远行的心 发表于 2018-8-19 07:00:54

Shell笔记1——变量核心知识

  本文档主要讲解Shell变量的核心基础知识与实践
  基本大纲:
  1.Shell变量的分类
  2.Shell中特殊且重要的变量
  3.bash Shell 内置变量命令详解
  4.Shell变量子串知识及实践
  5.Shell特殊扩展变量的知识与实践
  一:变量可分为两类:环境变量(全局变量)和普通变量(局部变量)。
  变量概念:简单地说、变量就是用一个固定的字符串(也可能是字符,数字等的组合)代替更多、更复杂的内容,该内容里可能还会包含变量、路径、字符串等其他的内容。
  1)环境变量:也可称为全局变量,可以在创建它们的Shell及其派生出来的任意子进程Shell中使用,环境变量又可分为自定义环境变量和bash内置的环境变量。(系统规范,所有的环境变量名字均采用大写形式)
  1.设置环境变量,三种方法
  ①export 变量名=value
  ②变量名=value;export 变量名
  ③declare -x 变量名=value
  2.用户的环境变量配置
  /root/.bashrc
  /root/.bash_profile
  小结:对于用户的环境变量设置,比较常见的是用户家目录下的.bashrc和.bash_profile这两个文件
  3. 全局环境变量的配置文件如下:
  /etc/profile
  /etc/bashrc
  /etc/profile.d/
  若是在登录后初始化或显示加载内容,则把脚本文件放在/etc/profile.d/下即可(无须加执行权限)
  4.定义环境变量的经验小结:
  ①变量名通常要大写
  ②常用export来定义环境变量
  ③用env和set显示默认的环境变量,用unset消除本地变量和环境变量。
  ④书写crond定时任务时要注意,脚本要用到的环境变量最好先在所执行的Shell脚本中重新定义。
  ⑤如果希望环境变量永久生效,则可以将其放在用户环境变量文件或全局环境变量文件里。
  2)普通变量:也可称为局部变量,只能在创建它们的Shell函数或Shell脚本中使用。普通变量一般由开发者在开发脚本程序时创建。
  1.设置普通变量,三种方法
  ①变量名=value      #此方法适合定义简单的数字,字符串,以及路径名
  ②变量名='value'    #此方法适合定义显示纯字符串,不解析变量,以及命令的场景
  ③变量名="value"   #此方法适合定义字符串中带有变量及命令,需要解析出来再输出的变量定义。定义变量加引号是最常见的使用场景
  定义变量经验:
  数字内容的变量定义可以不加引号,其他没有特殊要求的字符串等定义最好都加上双引号,如果真的需要原样输出就加单引号,定义变量加双引号是最常见的使用场景。
  2.把一个命令的结果作为变量的内容赋值,两种方法
  ①变量名=`ls`
  ②变量名=$(ls)    #推荐使用此法
  生产场景中把命令的结果做为变量的内容进行赋值的方法在脚本开发时很常见
  3.局部(普通)变量定义及赋值经验小结:
  ①若变量内容为连续的数字或字符串,赋值时,变量内容两边可以不加引号。例如:a=123,abc
  ②变量的内容很多时,如果有空格且希望解析内容中的变量,就加双引号。例如a="abc $USER",此时输出变量会对内容中的$USER进行解析然后再输出
  ③希望原样输出变量中的内容就用单引号引起内容进行赋值,例如:a='$USER' ,那么echo $a—> $USER
  ④命令的解析结果定义与赋值,要使用反引号将赋值的命令括起来,例如:a=`ls` ;或者用$()括起来,例如:a=$(ls)
  ⑤变量的输出方法:使用“$变量名”即可输出变量的内容,常用“echo $变量名”的方式,也可以用printf代替echo输出更复杂的格式内容
  ⑥用echo等命令输出变量的时候,也可用单引号、双引号、反引号,例如:echo $A 、echo '$A'、echo "$A",它们的用法和前面变量内容定义的总结是一致的。
  ⑦$dbname_tname,当变量后面连接有其他字符的时候,必须给变量名加上大括号{},例如:$dbname_tname改成${dbname}_tname
  #注:这些结论仅针对Linux Shell,sed和grep是一致的,只是对于awk语言有些特别
  awk结论:
  awk加单引号后再同时加双引号能保证都是正确输出。不管变量如何定义,赋值,除了加单引号外,利用awk直接获取变量的输出,结果都是一样的。因此,在awk取用shell变量时,我们更多地还是喜欢先用echo加符号输出变量,然后通过管道给awk,进而控制变量的输出结果。例如:echo $USER|awk '{print $0}'
  二:Shell中特殊且重要的变量
  1)Shell中的特殊位置参数变量
  $0    #获取当前执行的shell脚本的文件名,如果执行脚本包含了路径,那么就包含了路径,那么就包括脚本路径
  $n    #获取当前执行的Shell脚本的第n个参数值,n=1..9,当n为0时表示脚本的文件名;如果n大于9,则用大括号括起来,例如${10},接的参数一空格隔开
  $#    #获取当前执行的shell脚本后面接的参数的总个数
  $*    #获取当前shell脚本所有传参的参数,不加引号和$@相同;如果给$@加上双引号,例如:“$*”,则表示将所有的参数视为单个字符串,相当于“$1 $2 $3”
  $@    #获取当前shell脚本所有传参的参数,不加引号和$*相同;如果给$@加上双引号,例如:“$@”,则表示将所有的参数视为不同的独立字符串,相当于"$1""$2""$3""..."。这是将多参数传递给其它程序的最佳方式,因为它保留所有的内嵌在每个参数里的任何空白。当"$@"和"$*"都加双引号时,两者是有区别的;都不加双引号时,两者无区别
  2)Shell进程中的特殊状态变量
  $?      #获取执行上一个指令的执行状态返回值(0为成功,非零为失败),这个很常用
  $$   #获取当前执行的Shell脚本的进程号(PID),这个变量不常用
  $!   #获取上一行在后台工作的进程的进程号(PID),这个变量不常用
  $_   #获取在此之前执行的命令或脚本的最后一个参数,这个变量不常用
  注:$?:不同命令的执行结果中,$?的返回值不尽相同,但在工作场景中,常用的就是0和非0状态,0表示成功,非0表示运行失败或者未成功
  三:bash Shell 内置变量命令详解
  1.echo命令参数选项详解 :
  -n#不换行输出内容   -e#解析转义字符(见下面的字符)
  \n#换行   \r#回车      \t#制表符   \b#退格   \v#纵向制表符
  #注:printf和echo -e的转义字符能力相似
  2.eval
  命令格式:eval args
  功能:当shell程序执行到eval语句时,Shell读入参数agrs,并将它们组合成一个新的命令,然后执行
  # cat noeval.sh
  echo \$$#
  # sh noeval.sh 2 1
  $2
  # cat noeval.sh
  eval "echo \$$#"               #传入两个参数,$#为2,echo \$$#变为echo $2,再加上eval命令,使得$2重新解析输出,而不是本身。所以下面输出了2
  # sh noeval.sh 1 2
  2
  3.exec
  命令格式:exec命令参数
  功能:exec命令能够在不创建新的子进程的前提下,转去执行指定的命令,当指定的命令执行完毕后,该进程(也就是最初的Shell)就终止了,示例如下:
  # cat /tmp/tmp.log
  1
  2
  # cat exec.sh
  exec < /tmp/tmp.log      #读取log内容
  while read line          #利用read一行行读取处理
  do
  echo $line
  done
  echo OK
  # sh exec.sh
  1
  2
  OK
  4.read
  命令格式:read变量名表
  功能:从标准输入读取字符串等信息,传给shell程序内部定义的变量。
  read -p &quot;屏幕打印字符串:&quot; a
  echo$a    #从屏幕打印输出赋值给脚本变量使用
  5.shift
  命令格式:shift-Shift positional parameters
  功能:shift语句会按如下方式重新命名所有的位置参数变量,即$2成为$1,$3成为$2等,以此类推作用:很方便
  # set -- &quot;1&quot;&quot;2&quot;
  # shift
  # echo $1
  2
  shift生产环境案例:
  # sed 8,25p/usr/bin/ssh-copy-id -n
  ID_FILE=&quot;${HOME}/.ssh/id_rsa.pub&quot;
  if [ &quot;-i&quot; = &quot;$1&quot; ]; then
  shift

  # check if we have 2 parameters left, if so the first is the new>  if [ -n &quot;$2&quot; ]; then
  if expr &quot;$1&quot; : &quot;.*\.pub&quot; > /dev/null ; then

  >  else

  >  fi
  shift         # and this should leave $1 as the target name
  fi
  else
  if [ x$SSH_AUTH_SOCK != x ] ; then
  GET_ID=&quot;$GET_ID ssh-add -L&quot;
  fi
  fi
  6.exit
  命令格式:exit-Exit the shell
  功能:退出shell程序。在exit之后可以有选择地指定一个数位作为返回状态。
  四:Shell变量子串知识及实践
  1)变量子串介绍
  ①${parameter} #返回变量$parameter的内容
  ②${#parameter} #返回变量$parameter内容的长度(按字符),也适用于特殊变量
  ③${parameter:offset) #在变量${parameter}中,从位置offset之后开始提取子串到结尾
  ④${parameter:offset:length} #在变量${parameter}中,从位置offset之后开始提取长度为length的字串
  ⑤${parameter#word} #从变量${parameter}开头开始删除最短匹配的word子串
  ⑥${parameter##word} #从变量${parameter}开头开始删除最长匹配的word子串
  ⑦${parameter%word}#从变量${parameter}结尾开始删除最短匹配的word子串
  ⑧${parameter%%word} #从变量${parameter}结尾开始删除最长匹配的word子串
  ⑨${parameter/pattern/string}   #使用string代替第一个匹配的pattern
  ⑩${parameter//pattern/string} #使用string代替所有匹配的pattern
  2)变量子串实践
  1).${parameter}#返回变量$parameter的内容
  示例:
  # ywxi=&quot;I am ywxi&quot;
  # echo ${ywxi}
  I am ywxi
  2).${#parameter} #返回变量$parameter内容的长度(按字符),也适用于特殊变量
  示例:
  # echo ${#ywxi}
  9
  # echo $ywxi|wc -L
  9
  # expr length &quot;$ywxi&quot;
  9
  # echo $ywxi|awk '{print length'&quot;$0&quot;'}'
  9
  3).${parameter:offset) #在变量${parameter}中,从位置offset之后开始提取子串到结尾
  示例:
  # echo ${ywxi}
  I am ywxi
  # echo ${ywxi:2}
  am ywxi
  4).${parameter:offset:length} #在变量${parameter}中,从位置offset之后开始提取长度为length的字串
  示例:
  # echo ${ywxi}
  I am ywxi
  # echo ${ywxi:2:2}
  am
  等价于
  # echo ${ywxi}|cut -c 3-4
  am
  5).${parameter#word} #从变量${parameter}开头开始删除最短匹配的word子串
  示例:
  # ywxi=abcABC123ABCabc
  # echo ${ywxi#a*C}
  123ABCabc
  # echo ${ywxi#a*c}
  ABC123ABCabc
  6).${parameter##word} #从变量${parameter}开头开始删除最长匹配的word子串
  示例:
  # echo $ywxi
  abcABC123ABCabc
  # echo ${ywxi##a*c}
  # echo ${ywxi##a*C}
  abc
  7).${parameter%word}#从变量${parameter}结尾开始删除最短匹配的word子串
  示例:
  # echo $ywxi
  abcABC123ABCabc
  # echo ${ywxi%a*c}
  abcABC123ABC
  # echo ${ywxi%a*C}
  abcABC123ABCabc
  8).${parameter%%word} #从变量${parameter}结尾开始删除最长匹配的word子串
  示例:
  # echo $ywxi
  abcABC123ABCabc
  # echo ${ywxi%%a*c}
  # echo ${ywxi%%a*C}
  abcABC123ABCabc
  有关匹配删除的小结:
  #表示从开头删除匹配最短
  ##表示从开头删除匹配最长
  %表示从结尾删除匹配最短
  %%表示从结尾删除匹配最长
  a*c表示匹配的字符串,*表示匹配所有,a*c匹配开头为a、中间为任意多个字符、结尾为c的字符串
  a*C表示匹配的字符串,*表示匹配所有,a*c匹配开头为a、中间为任意多个字符、结尾为C的字符串
  9).${parameter/pattern/string}   #使用string代替第一个匹配的pattern
  示例:
  # ywxi=&quot;I am oldboy,yes,oldboy&quot;
  # echo $ywxi
  I am oldboy,yes,oldboy
  # echo ${ywxi/oldboy/oldgirl}
  I am oldgirl,yes,oldboy
  10).${parameter//pattern/string} #使用string代替所有匹配的pattern
  示例:
  # echo ${ywxi//oldboy/oldgirl}
  I am oldgirl,yes,oldgirl
  有关替换的小结:
  #一个&quot;/&quot;表示替换匹配的第一个字符串
  #两个&quot;/&quot;表示替换匹配的所有字符串
  五:Shell特殊扩展变量的知识与实践
  1)特殊扩展变量介绍
  ①${parameter:-word}   #用途:如果变量未定义,则返回备用的值,防止变量为空值或因未定义而导致异常
  ②${parameter:=word}   #用途:基本同上一个${parameter:-word},但该变量又额外给parameter变量赋值了
  ③${parameter:?word}   #用途:用于捕捉由于变量未定义而导致的错误,并退出程序
  ④${parameter:+word}   #如果parameter变量值为空或未赋值,则什么都不做,否则word字符串将替代变量的值
  2)特殊扩展变量实践
  shell范例11:
  1)${parameter:-word}   #用途:如果变量未定义,则返回备用的值,防止变量为空值或因未定义而导致异常
  # echo $test
  # result=${test:-UNSET}
  # echo $result
  UNSET
  # echo $test
  #
  # test=oldboy
  # echo $test
  oldboy
  # result=${test:-UNSET}
  # echo $result
  oldboy
  # echo $test
  oldboy
  # result=${test-UNSET}
  # echo $result
  oldboy
  2)${parameter:=word}   #用途:基本同上一个${parameter:-word},但该变量又额外给parameter变量赋值了
  # result=${test:=UNSET}
  # echo $result
  UNSET
  # echo $test
  UNSET
  # result=${test=UNSET}
  # echo $result
  UNSET
  # echo $test
  UNSET
  3)${parameter:?word}   #用途:用于捕捉由于变量未定义而导致的错误,并退出程序
  # echo ${key:?not defined}
  -bash: key: not defined
  # key=1
  # echo ${key:?not defined}
  1
  # echo ${key?not defined}
  1
  # unset key
  # echo ${key:?not defined}
  -bash: key: not defined
  4)${parameter:+word}   #如果parameter变量值为空或未赋值,则什么都不做,否则word字符串将替代变量的值
  # unset oldboy
  # unset oldgirl
  # oldboy=${oldgirl:+word}
  # echo $oldboy
  # oldgirl=19
  # oldboy=${oldgirl:+word}
  # echo $oldboy
  word
  http启动服务示例:
  # cat /etc/init.d/httpd
  HTTPD_LANG=${HTTPD_LANG-&quot;C&quot;}   #如果变量HTTPD_LANG未定义,则返回C,防止异常
  httpd=${HTTPD-/usr/sbin/httpd}         #如果HTTPD未定义,则返回/usr/sbin/httpd,防止异常
  pidfile=${PIDFILE-/var/run/httpd/httpd.pid}   #如果PIDFILE未定义,则返回/var/run/httpd/httpd.pid,防止异常
  lockfile=${LOCKFILE-/var/lock/subsys/httpd}   #如果LOCKFILE未定义,则返回/var/lock/subsys/httpd,防止异常

页: [1]
查看完整版本: Shell笔记1——变量核心知识