设为首页 收藏本站
查看: 1130|回复: 0

shell笔记_01

[复制链接]

尚未签到

发表于 2015-12-15 15:21:28 | 显示全部楼层 |阅读模式
DSC0000.png
  音符~Linux
  

  Shell编程学习笔记
  

  1.对shell的介绍
  1)什么是shell?
  Shell它是一个命令解释器,负责直接与用户对话,把用户的输入解释给操作系统,并 处理各种各样的操作系统的输出结果,输出到屏幕返回给用户。这种对话方式可以是交 互的方式(从键盘输入命令,可以立即得到shell的回应),或非交互(脚本)的方式。
DSC0001.png
  2)什么是shell脚本?
  当命令或语句不在命令行执行,而是通过一个程序文件执行时,该程序就被称为shell脚本或shell程序,shell程序很类似DOS系统下的批处理程序(*.bat)。用户可以在shell脚本中桥如一系列的命令或命令语句。这些命令、变量和流程控制语句等有机的结合起来就形成了一个强大的shell脚本。
  范例:1清空/var/log/messages日志文件的简单命令
  我们使用脚本log.sh进行操作
  #!/bin/bash
  #清除日志脚本,版本2
  LOG_DIR=/var/log
  ROOT_UID=0      #$UID为0的时候,用户才具有root用户的权限
  #要使用root用户来运行.
  if [ "$UID" -ne "$ROOT_UID" ]
  then
echo "Must be root to run this script."
exit 1
  fi
  cd $LOG_DIR || {
echo "Cannot change to necessary directory." >&2
exit 1
  }
  cat /dev/null > messages && echo "Logs cleaned up."
  exit 0  //这里退出之前返回0表示成功。返回1表示失败。
  [iyunv@server2 log]# sh log.sh
  Logs cleaned up.
  下面我们给出几种不同的清空日志的方法
  第一种
  [iyunv@server2 ~]#echo " " > test.log
  第二种
  [iyunv@server2 ~]#echo > test.log
  第三种
  [iyunv@server2 ~]#cat /dev/null > test.log
  应用场合:保留文件,清空内容

  运维开发人员常用的脚本语言:
  Php(主要是做网页程序,也是脚本语言)
  Perl
  Python(现在已经成为主流)

  Linux默认的shell是bash
  [iyunv@server2 log]# echo $SHELL //我们可以使用这个命令进行查看
  /bin/bash
  3)写脚本应该注意的几点:
a)要写注释
b)在执行的时候可以使用全路径进行执行或在当前路径执行这种情况需要有-x执行权限
c)用source filename和. filename来执行

  
  2.一些简单的操作
  #cat > test.sh
  echo hello,we are yanghaiying.
  1)脚本执行的方法:
  ctrl+D/ctrl+c可以直接保存,但是这样只能使用shell解释器去执行shell程序
  如果想要执行,我们需要使用chmod +x test.sh
  #source test.sh  / #. test.sh
  a)这两种做法我们都可以进行test.sh执行,可以直接调用脚本里面的函数,
  b)但是如果这个脚本没有可执行权限的时候,使用sh不能直接调用脚本里面的函数、变量等等,所以一般情况下推荐使用上面两种方法。
  eg:
  [iyunv@server2 ~]# cat  >test.sh
  user=`whoami`
  [iyunv@server2 ~]# sh test.sh
  [iyunv@server2 ~]# echo $user
  
  [iyunv@server2 ~]# source test.sh 或者 . test.sh
  [iyunv@server2 ~]# echo $user
  root
  
  2)脚本的书写规范
  a)指定解释器,加版权等信息
  #!/bin/bash
  # Date 2015-01-13
  # Author:Created by hy
  # Mail:1020659371@qq.com
  # Function:This scripts function is MySQL backup
  # V2.1
  b)不要使用中文注释
  c)脚本以.sh为扩展名,例:script-name.sh
  d)成对的内容,一次性写出来,防止遗漏,如:{},[],'',``,""等
  e)[]中括号两端有空格,例如:[ abc ]
  f)在写一些程序的时候我们要将一些语句块的前后首先对应写出来,例如:
  if语句格式一次完成:
  if 条件
  then
  语句(一般是语法写全了后中间再加语句)
  fi
  
  for循环格式一次完成:
  for n in list
  do
  语句(一般是语法写全了后中间再加语句)
  done
  提示:while和until,case等语句也是一样。
  g)学会缩进,让代码更易读
  多行同时缩进的操作,ctrl+v-->选定要缩进的行-->按TAB(如果进行注释按#)
  -->按Esc
  
  
  3.环境变量
  3.1全局变量的设置
  在 /etc/profile或在/etc/profile.d/*.sh
  例如:
  TMOUT=3600:可以设置推出前等待超时的秒数
  UID=0:当前用户的UID
  HISTFILESIZE=50:历史文件包含的最大行数
  HISTSIZE=50:记录在命令行历史文件中的命令行数
  3.2自定义环境变量(全局变量)
  设置环境变量:如果想设置环境变量,就要在给定变量赋值之后或设置变量时使用export命令。带-x选项的declare内置命令也可以完成同样的功能。
  (注意:输出变量时不要在变量名前面加$)
  --
  -f
  -n
  -p
  格式:
  1)export 变量名=value
  2)变量名=value;export 变量名
  3)declare -x 变量名=value
  提示:以上为三种设置环境变量的方法
  例如:
  export NAME=hy
  declare -x NAME=hy
  NAME=hy;export NAME
  eg:
  [iyunv@server2 ~]# export NAME=hy
  [iyunv@server2 ~]# echo $NAME
  hy
  [iyunv@server2 ~]# declare -x name=hy
  [iyunv@server2 ~]# echo $name
  hy
  
  如何取消环境变量的定义:unset 变量名
  3.3局部变量
  变量名='value'
  变量名="value"
  shell中变量名的要求:一般是字母,数字,下划线组成。字母开头。hy,hy123,hy_trip.
  eg:
  [iyunv@server2 ~]# a=192.168.2.2
  [iyunv@server2 ~]# b='192.168.2.2'
  [iyunv@server2 ~]# c="192.168.2.2"
  [iyunv@server2 ~]# echo "a=$a"
  a=192.168.2.2
  [iyunv@server2 ~]# echo "b=$b"
  b=192.168.2.2
  [iyunv@server2 ~]# echo "c=$c"
  c=192.168.2.2
  [iyunv@server2 ~]# echo "c=${c}"
  c=192.168.2.2
  [iyunv@server2 ~]# a=192.168.2.2-$a
  [iyunv@server2 ~]# b='192.168.2.2-$a'
  [iyunv@server2 ~]# c="192.168.2.2-$a"
  [iyunv@server2 ~]# echo "a=$a"
  a=192.168.2.2-192.168.2.2
  [iyunv@server2 ~]# echo "b=$b"
  b=192.168.2.2-$a
  [iyunv@server2 ~]# echo "c=$c"
  c=192.168.2.2-192.168.2.2-192.168.2.2
  提示:
  第一种定义a变量的方式是直接定义变量内容,内容一般为简单连续的数字、字符串、路径名等。
  第二种定义b变量的方式是通过单引号定义变量。这个方式的特点是:输出变量时引号里是什么就输出什么,即使内容中有变量也会把变量名原样输出。此法比较适合于定义显示春字符串。
  第三中定义c变量方式是通过双引号定义变量。这种方式的特点是输出变量时引号里的内容会经解析后输出该变量内容,而不是把引号中变量名原样输出,适合于字符串附带有变量的内容的定义。
  
  特殊的:在awk里面刚好相反
  [iyunv@server2 ~]# awk 'BEGIN {print '$a'}'
  192.1680.2-191.9680.20.2
  [iyunv@server2 ~]# awk 'BEGIN {print "$a"}'
  $a
  3.4全局变量和局部变量名的定义
  a.脚本中的全局变量定义,如HY_HOME或HYHOME,在变量使用{}将变量括起或"${HY_HOME}" (当然这个不是必须的,这只是系统的一个规范)
  b.脚本中局部变量定义:存在于脚本函数(function)中的变量称为局部变量,要以local方式进行声明,使之只在本函数作用域内有效,防止变量在函数中的命名与变量外部程序中变量重名造成程序异常。下面是函数的变量定义例子:
  function TestFunc()
  {
  local i
  for((i=0;i128  命令被系统强制结束
  
  
  3)对$?的说明
  
  #!/bin/bash
  cd /etc
  tar zcf services.tar.gz ./services >&/dev/null
  [ $? -eq 0 ] && echo ok
  如果我们在命令行执行会输出ok,如果我们不加打包时候的参数,将没有输出结果
  
  4) $*和$@的区别例子
l $* 将所有的命令行所有参数视为单个字符串,等同于“$1$2$3”
l $@ 将命令行每个参数视为单独的字符串,等同于“$1”,“$2”,“$3”。这是将参数传递给其他程序的最佳方式,因为他会保留所有内嵌在每个参数里的任何空白。
  实例:
  [iyunv@server2 ~]#set -- “I am” handsome hy.
  [iyunv@server2 ~]#echo $#
  3
  [iyunv@server2 ~]#for i in $*;do echo $i;done
  I
  am
  handsome
  hy.
  [iyunv@server2 ~]#for i in $@;do echo $i;done
  I
  am
  handsome
  hy.
  [iyunv@server2 ~]#for i;do echo $i;done  //去掉in 变量列表,相当于in “$@”
  I am
  handsome
  hy.
  [iyunv@server2 ~]#for i in “$*”;do echo $i;done
  I am handsome hy.  //这里不是说输出到一行,而是将所有的字符当成一个字符串
  
  5)Shift的使用
  [iyunv@server2 ~]#shift  //该命令是将字符进行退格处理
  [iyunv@server2 ~]#echo $1
  handsome
  [iyunv@server2 ~]#echo $2
  hy.
  [iyunv@server2 ~]#echo $3 //这时我们可以看到$3的输出结果为空
  可以less /usr/bin/ssh-copy-id查看这个shell文件,他里面就用到了shift
  网上查看eval的使用:http://oldboy.blog.iyunv.com/2561410/1175971
  3.7对变量的操作
DSC0002.png
  [iyunv@server2 ~]#hy=”I am hy.”
  [iyunv@server2 ~]#echo ${#hy}
  8
  [iyunv@server2 ~]#echo $hy | wc -m
  9
  截取hy变量字符串从第2个字符之后开始取,默认取后面字符的全部,第二个字符不包含在内。也可理解为删除前面的多少个字符。例:
  [iyunv@server2 ~]#echo ${hy:2}
  am hy.
  
  [iyunv@server2 ~]#echo ${hy:2:2}
  am
  [iyunv@server2 ~]#echo ${hy} | cut -c 1-4  //也可以使用cut来进行截取
  I am
  [iyunv@server2 ~]#echo ${hy} | cut -c 3-4
  am
  从变量$hy开头开始删除最短匹配“I am”子串
  [iyunv@server2 ~]#echo ${hy#I am}
  hy.
  [iyunv@server2 ~]#echo ${hy##I am h}
  y.
  从变量$hy结尾开始删除最短匹配
  [iyunv@server2 ~]#echo ${hy%hy.}
  I am
  [iyunv@server2 ~]#echo ${hy%I am} //这样就不行
  I am hy.
  从变量$hy结尾开始删除最长匹配
  [iyunv@server2 ~]#echo ${hy%%hy}
  使用etiantian字符串,来代替变量$hy第一个匹配的hy字符串
  [iyunv@server2 ~]#echo ${hy/I am/you are}
  you are hy.
  使用etiantian字符串,来代替变量$hy结尾开始匹配的hy字符串
  [iyunv@server2 ~]#echo ${hy/%hy/server}
  I am server
  使用 he is 字符串,来代替从变量$hy开头开始匹配I am字符串
  [iyunv@server2 ~]#echo ${hy/#I am/he is}
  he is hy.
  
  
  生产场景用法实例:
  1)变量结尾删除生产实践:
  功能描述如下表:
  ${string%substring} 从变量$string结尾开始删除最短匹配$substring子串
  批量文件改名案例实践:
  问题1:把下面所有文件的文件名中的finished内容去掉
  首先我们创建几个文件:
  [iyunv@server2 ~]#for i in $(seq 4);do touch stu_20150117_”$i”_finished.jpg;done
  [iyunv@server2 ~]#ll  我们可以看到这四个文件被创建
  [iyunv@server2 ~]#cat file
  stu_20150117_1_finished.jpg
  stu_20150117_2_finished.jpg
  stu_20150117_3_finished.jpg
  stu_20150117_4_finished.jpg
  [iyunv@server2 ~]#for i in `cat file`;done mv $i `echo ${i/%finished.jpg/.jpg}`;done
  [iyunv@server2 ~]#ls -1
  stu_20150117_1_.jpg
  stu_20150117_2_.jpg
  stu_20150117_3_.jpg
  stu_20150117_4_.jpg
  [iyunv@server2 ~]#test=”stu_20150117_1_finished.jpg”
  [iyunv@server2 ~]#echo ${test%finished*}.jpg
  stu_20150117_1_.jpg
  注:这两行语句是做一个测试,这是处理这类批量处理问题的思路,先从一个出发
  当然这个也可以使用ls加awk来实现
  #ls | grep stu | awk -F “finished” ‘{print $1$2}’ 可以达到同样的效果
  #ls | grep stu | awk -F “finished” ‘{print “mv “$0” “$1$2” “}’ | /bin/bash
  #rename finished “” *  这两个也可以完成所需的操作
DSC0003.png
  
  其他变量的替换:
  变量替换表:
DSC0004.png
  
  [iyunv@server2 ~]#result=${test:-UNSET}   但有些脚本(像httpd启动脚本)里面是去掉”:”号也可以,这里我们可以在/etc/init.d/里面的脚本对比着看
  [iyunv@server2 ~]#echo $result
  unset
  [iyunv@server2 ~]#echo $test
  这里是空
  [iyunv@server2 ~]#test=”hy”
  [iyunv@server2 ~]#result=${test:-UNSET}  //我们可以看到result被重新赋值
  [iyunv@server2 ~]#echo $result
  hy
  [iyunv@server2 ~]#echo $test
  hy
  [iyunv@server2 ~]#unset test  //这部操作是取消test的值
  [iyunv@server2 ~]#unset result
  [iyunv@server2 ~]#result=${test:=UNSET}
  [iyunv@server2 ~]#echo $result
  UNSET
  [iyunv@server2 ~]#echo $test
  UNSET    //这时我们发现test不为空
  
  简单说明一下后面两个的测试结果:
  ${value:? “not define”}是用来捕捉由于变量未定义而导致的错误,如:”not defined”.
  [iyunv@server2 ~]#echo ${value:? “not define”}
  -bash:value: not defined
  [iyunv@server2 ~]#value=1
  [iyunv@server2 ~]#echo ${value:? ”not defined”}
  1
  
  ${value:+word}
  [iyunv@server2 ~]#r=${value:+1}
  [iyunv@server2 ~]#echo $r
  是空的
  [iyunv@server2 ~]#value=hy
  [iyunv@server2 ~]#r=${value:+1}
  [iyunv@server2 ~]#echo $r
  1
  
  以上有什么用途那?有时候我们可能定期需要清理磁盘缓存信息我们就可以使用这个定义好的变量直接指定
  [iyunv@server2 ~]#path1=”/tmp”
  [iyunv@server2 ~]#rm -fr ${path1-/tmp}  这是防止我们可能没有保存path1的值,就很危险,有可能他会从根开始删除,这样做他就会去直接删除/tmp里面的文件
  我们可以将其写在一个脚本里面看看执行结果:
  d.sh
  #!/bin/bash
  path=/mnt/backup
  find ${path:=/tmp/} -name “*.tar.gz” -type f  | xargs rm -f
  [iyunv@server2 ~]#sh -x d.sh  //跟踪执行
  + path=/mnt/backup
  + xargs rm -f
  + find /mnt/backup -name ‘*.tar.gz’ -type f
  [iyunv@server2 ~]#vim d.sh  //我们将第一行注释掉
  #!/bin/bash
  #path=/mnt/backup
  find ${Path:=/tmp/} -name “*.tar.gz” -type f  | xargs rm -f
  [iyunv@server2 ~]#sh -x d.sh  //跟踪执行结果,他会在/tmp这个目录里面去找
  + xargs rm -f
  + find /tmp -name ‘*.tar.gz’ -type f
  
  邮箱:g2hy@qq.com
  
  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-151660-1-1.html 上篇帖子: shell笔记_02 下篇帖子: shell的初步认识2
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表