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

shell脚本的基础1

[复制链接]
YunVN网友  发表于 2018-8-27 10:39:35 |阅读模式
  shell脚本的基础
  1.shell 脚本的编写规范
  2 变量与特殊变量应用
  3局部变量与全局变量
  4 测试判断表达式
  在一些复杂的Linux维护工作中,大量重复的输入和交互操作不但费时费力,而且容易出错.
  编写脚本的好处:
  批量的处理,自动化的完成维护,减轻管理员的负担.
  linux的shell脚本是一种特殊的应用程序,常见的shell解释器有很多种使用不同的shell时期内部指令命令提示方式方面会存在一些区别,可以通过/etc/shells文件查看
  [root@RHEL7 ~]# cat /etc/shells
  /bin/sh
  /bin/bash
  /sbin/nologin
  /usr/bin/sh
  /usr/bin/bash
  /usr/sbin/nologin
  /bin/tcsh
  /bin/csh
  /bin/bash是大多数linux中默认的shell解释器。之后的所有脚本的编写都是bash脚本
  编写第一个Shell脚本
  将平时的操作命令顺序的放入到文件中赋予执行权限,一次的执行
  我们来编写第一个脚本frist.sh
  linux不以后缀名区分文件,为了方便记忆这里我就以.sh为结尾
  [root@RHEL7 1607]# cat firsh.sh
  #!/bin/bash
  #This is my first shell scripts
  注释:
  #!/bin/bash 主要是为了声明,我所写的均为bash语言(我是用的是bash解释器)
  第二行为注释行,注释信息不生效
  当写一个比较大的脚本时,如果没有一个好的注释,那么也就也就没有人都能够看懂其中的意思了
  再往后即执行的命令
  执行脚本的不同方式
  第一种使用绝对路径执行
  第二种使用相对路径执行,如./的方式
  第三种使用 sh命令来执行  格式  sh 脚本名   不需要执行权限
  第四种使用 . (空格)脚本名称的方式执行  不需要执行权限  . a.sh
  第五种使用 source 脚本名称        不需要执行权限
  建议使用后三种,在生产环境中不要轻易的给文件可执行权限;
  接下来我们来探讨脚本中作重要的东西---变量
  变量的定义是:可以存放一个可变的值的空间
  可以通过不同的环境进行改变就是一个可以变的值
  常见的shell变量有自定义变量、环境变量、位置变量、预定义变量
  一般使用echo 输出变量  变量名的格式=$变量名
  echo $? echo $变量名
  1、自定义变量
  自定义变量是用户根据自己的环境自己定义的变量
  Bash中比较简单的变量,不用进行提前声明,而是直接指定变量名称并赋给初始值;
  定义变量的基本格式为变量名=变量值等号两遍不允许出现空格;
  变量名称只能以字母和下划线开头名称中不能包含+、- * 、 / . , 、 ? % * ……等一些特殊字符
  举例:
  来进行定义一个变量名字为Linux值为7.2  (注意大小写)
  [root@RHEL7 1607]# Linux=7.2
  [root@RHEL7 1607]# echo $Linux
  7.2
  [root@RHEL7 1607]# linux=7.0
  [root@RHEL7 1607]# echo $linux
  7.0
  可以直接在命令行定义,以上就是定义一个变量并赋予值,通过echo进行输出变量 $是引用变量的特殊字符(必须使用$符号)
  echo和调用的变量之间必须要有空格
  举例2:
  当需要一起调用两组变量时
  [root@RHEL7 1607]# echo $Linux $linux
  7.2 7.0
  直接使用echo 后面跟$调用的变量如果有多个则空格隔开
  举例3:
  当变量名和后面的字符容易混淆的时候应该使用{}将变量名括起来
  [root@RHEL7 1607]# echo ${Linux}system
  7.2system
  [root@RHEL7 1607]# echo ${linux}system
  7.0system
  变量值还有一些其他的特殊操作
  双引号( " )
  当=号右边赋值出现空格的时候,需要使用双引号将其扩起
  [root@RHEL7 ~]# version="rehdat9.0"
  [root@RHEL7 ~]# echo $version
  rehdat 9.0
  在双引号的范围内还可以引用其他的变量,从而能够将现有的变量赋值给新的变量
  [root@RHEL7 ~]# Linux=7.2
  [root@RHEL7 ~]# system="RHEL$Linux"
  [root@RHEL7 ~]# echo $system
  RHEL 7.2
  单引号( ' )
  当要赋值的内容包括"$"、"\"等,具有其他含义的特殊字符时,
  应使用单引号将其括起来
  在单引号范围内将无法引用其他的值,任何字符均作为普通字符看待,但赋值 的内容包含单引号时需要使用\’符号进行转义以免冲突
  反撇号( ` )
  在键盘esc的下边的按键。
  反撇号主要使用于命令替换,允许将某个命令的屏幕输出结果赋值给变量。
  反撇号括起来的范围内必须是可执行的命令。否则将会出现错误
  举例:
  在命令行中查找程序的详细的信息
  [root@RHEL7 1607]# rpm -qf `which pwd`
  coreutils-8.22-11.el7.x86_64
  [root@RHEL7 1607]# rpm -qf $(which pwd)
  coreutils-8.22-11.el7.x86_64
  需要注意的是使用反撇号难以在一条命令中实现嵌套命令的操作,这是可以$()来替代反撇号
  [root@RHEL7 1607]# rpm -q `rpm -qf `whichls``
  rpm: no arguments given for query
  which-2.20-7.el7.x86_64
  package ls is not installed
  [root@RHEL7 1607]# rpm -q $(rpm -qf $(whichpwd))
  coreutils-8.22-11.el7.x86_64
  4)read命令
  除了上面的赋值之外还可以使用read命令进行赋值,read命令用来提示用户输入信息,从而实现简单的交互式过程(其实我们所输入的命令就是一种交互式的过程)
  执行时需要从标准输入设备键盘读取一行,并以空格为分隔符
  比如我同时定义两个变量操作如下所示
  [root@RHEL7 shell]# read kernel system
  3.10 7.2
  [root@RHEL7 shell]# echo $kernel
  3.10
  [root@RHEL7 shell]# echo $system
  7.2
  为了交互式更加的形象,提高易用性,加上 -p选项来设置提示信息
  [root@RHEL7 shell]# read -p "Inputyour password:" passwd
  Input your password:123456
  [root@RHEL7 shell]# echo $passwd
  123456
  我们以上的操作只是在当前的bash环境下生效,到了其他控制台或者是其他shel就不能生效了
  我们进入当前shell的子shell
  [root@RHEL7 shell]# echo $Linux
  7.2
  [root@RHEL7 shell]# bash                            进入子shell
  [root@RHEL7 shell]# echo $Linux
  [root@RHEL7 shell]# exit                      #exit退出当前的bash回到父bash
  exit
  [root@RHEL7 shell]# echo $Linux
  7.2
  进入子shell之后在局部定义的变量就不会生效了。只能说明一点,当前bash内不存在输出的变量
  通过set查看当前的所有变量
  通过env查看全局变量
  [root@RHEL7 shell]# env
  XDG_SESSION_ID=72
  HOSTNAME=RHEL7.2
  SELINUX_ROLE_REQUESTED=
  TERM=xterm
  SHELL=/bin/bash
  HISTSIZE=1000
  SSH_CLIENT=192.168.137.1 61008 22
  SELINUX_USE_CURRENT_RANGE=
  SSH_TTY=/dev/pts/0
  USER=root
  将一个局部变量改变为全局变量
  [root@RHEL7 shell]# export city=shengzheng            #设置为 全局变量
  [root@RHEL7 shell]# bash                                          #进入子shell
  [root@RHEL7 shell]# echo $city
  shengzheng
  需要注意的是变量的名是严格区分大小写的
  数值变量的运算
  shell脚本的数值运算多用于脚本程序的过程控制(如循环次数,使用量比较等)
  在shell环境中,只能进行比较简单的整数运算
  运算符与变量之间必须有一个空各位,整数的运算主要是通过内部命令expr 命令尽心运算
  格式  变量1 运算符 变量2
  其中 变量1 、变量2 ……对应的需要计算的数值变量(需要$符号调用)常用的几种运算符如下所示
  加法运算:+
  减法运算: -
  乘法运算: \*
  除法运算: /
  求模(取余)运算: %
  [root@RHEL7 shell]# A=100
  [root@RHEL7 shell]# B=200
  [root@RHEL7 shell]# expr $A+$B
  100+200
  [root@RHEL7 shell]# expr $A + $B
  300
  [root@RHEL7 shell]# expr $A - $B
  -100
  [root@RHEL7 shell]# expr $A \* $B
  20000
  [root@RHEL7 shell]# expr $A * $B
  expr: syntax error
  [root@RHEL7 shell]# expr $A / $B
  0
  [root@RHEL7 shell]# expr $A % $B
  100
  若要将运算结果赋值给其他变量可以这么做
  [root@RHEL7 shell]# A=$(expr $A + $B)
  [root@RHEL7 shell]# echo $A
  300
  自定义变量就讲到这里
  环境变量:
  环境变量是指系统本身运行需要由linux系统提前创建好的一类变量.
  主要用于用户的工作环境,包括(用户的宿主目录,命令的查找路径,用户的当前目录,登录的终端等)环境变量的值由操作系统本身自己维护,随着用户的状态改变而改变
  env调取当前环境变量
  [root@RHEL7 shell]# env
  XDG_SESSION_ID=72
  HOSTNAME=RHEL7.2
  SELINUX_ROLE_REQUESTED=
  SHELL=/bin/bash
  TERM=xterm
  HISTSIZE=1000
  SSH_CLIENT=192.168.137.1 61008 22
  SELINUX_USE_CURRENT_RANGE=
  SSH_TTY=/dev/pts/0
  USER=root
  环境变量的配置文件在/etc/profile(全局)
  用户宿主目录/home/zhangsan/.bash_profile(局部)
  $PWD
  pwd命令就是调用了这个变量才能进行输出
  [root@RHEL7 shell]# echo $PWD
  /root/shell
  [root@RHEL7 shell]# cd /home
  [root@RHEL7 home]# echo $PWD
  /home
  $PATH
  定义命令的默认搜索路径,我们讲的mysql可执行程序优化的时候我们是直接将程序路径写到了这个变量中才可以再任何目录下进行输入.
  [root@RHEL7 shell]# echo $PATH
  /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
  $USER
  [root@RHEL7 shell]# echo $USER
  root
  [root@RHEL7 shell]# su - andy
  Last login: Fri Aug  5 21:18:30 CST 2016 on pts/2
  [andy@RHEL7 ~]$ echo $USER
  andy
  $SHELL
  [root@RHEL7 shell]# echo $SHELL
  /bin/bash
  $HOME
  [root@RHEL7 shell]# echo $SHELL
  /bin/bash
  [root@RHEL7 shell]# echo $HOME
  /root
  [root@RHEL7 shell]# su - andy
  Last login: Tue Aug 30 21:35:02 CST 2016 onpts/0
  [andy@RHEL7 ~]$ echo $HOME
  /home/andy
  将我们所写的脚本放到$PATH的默认搜索路径中去
  1.将/root目录写入到PATH的环境变量中,但是还没有永久生效
  [root@RHEL7 shell]# pwd
  /root/shell
  [root@RHEL7 shell]# PATH="$PATH:/root/shell"
  [root@RHEL7 shell]# echo $PATH
  /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/root/shell
  [root@RHEL7 shell]# ./first_shell.sh
  hello world
  [root@RHEL7 shell]#
  2.刷新一下/etc/profile 配置文件就可以永久生效了
  [root@RHEL7 shell]# vim /etc/profile
  3.之后/root下的可执行程序可以在任何目录下直接执行执行不许要任何命令去执行
  [root@RHEL7 shell]# ./first_shell.sh
  hello world
  [root@RHEL7 shell]# first_shell.sh
  hello world
  2、位置变量
  为了使用shell脚本程序:是方便通过命令行为程序提供参数Bash引用了位置变量的概念,
  当执行命令行操作时第一个字段表示命令字或程序名,其余的字符串参数按照从左到右的顺序依次给位置变量赋值
  位置变量也成为位置参数,使用$1 $2 $3 …$9表示
  以ls -lh /boot/为例
  其中除了 ls 之外的都是位置参数
  -lh是一个位置参数使用$1表示依次往后排,(空格分隔)
  $0属于预定义变量而不是位置变量
  3、预定义变量
  $#:命令行中位置变量的个数(程序执行了几个位置参数)
  $*:所有位置变量的内容(具体的内容 比如/boot就是一个具体的内容)
  $?:上一条命令执行后返回的状态,当返回状态值为0时表示执行正常,非0值表示执行异常或出错
  判断是否出现错误正常为0异常错误为非0取值在1-127之间
  $0:当前执行的进程/程序名(就是当前执行的命令或程序的名字)
  [root@RHEL7 shell]# cat shell.sh
  #!/bin/bash
  SUM=$(expr $1 + $2)
  echo "$1 + $2 = $SUM"
  [root@RHEL7 shell]# sh shell.sh 1 2
  1 + 2 = 3
  我们通过一个例子来解释
  vim backup.sh  编译一个使用打包命令打包多个目录或文件
  [root@RHEL7shell]# cat backup.sh
  #!/bin/bash
  file=back-$(date +%s).tar.gz
  tar zcf $file $* &>/tmp/tar.log
  echo "执行了$0个脚本"
  echo "共完成$#个备份对象"
  echo "具体内容包括$*"
  [root@RHEL7 shell]# sh backup.sh/root/shell/ /boot
  执行了backup.sh个脚本
  共完成2个备份对象
  具体内容包括/root/shell/ /boot
  一种是使用test命令进行判断 另外一种就是 [   ]命令
  test 条件表达式
  [ 条件表达式 ]
  1、文件测试
  文件测试是指根据给定的路径名称,判断是文件还是目录,判断是具有读写执行的权限,判断文件目录是否存在
  常用的选项如下
  -d:测试是否为目录(Directory)或目录是否存在
  -e:测试目录或文件是否存在(Exist)
  -f:测试是否为文件(File)或文件是否存在
  -r:测试当前用户是否有权限读取(Read)
  -w:测试当前用户是否有权限写入(Write)
  -x:测试当前用户是否有权限执行(eXcute)
  其中-e选项是判断的是文件还是目录,这个选项不是很常用,
  因为当你要判断文件的时候正好你指定的目录里面有一个和你要判断的文件重名的子目录,这样也会返回0的所以不是很常用.
  如果判断目录或文件是否存在只需要使用-d 或-f 来判断就可以了
  后面的三个测试权限的选项就是测试指定的文件或目录是否有读写执行的权限
  执行测试条件之后通过预定义变量$?可以测试命令的返回状态,从而判断是否存存在
  举例:一般我们挂在光盘的时候习惯将光盘挂载在/media/cdrom这个目录,但是rhel系统默认不存在这个目录,这时我们可以先判断一下这个目录是否存在
  [root@RHEL7 shell]# [ -d /mnt ]
  [root@RHEL7 shell]# echo $?
  0
  [root@RHEL7 shell]# ls /mnt
  addons isolinux       repodata
  EFI    LiveOS        RPM-GPG-KEY-redhat-beta
  EULA   media.repo     RPM-GPG-KEY-redhat-release
  GPL    Packages       TRANS.TBL
  images release-notes
  [root@RHEL7 shell]# echo $?
  0
  我们使用[ ]的这种方式进行判断,这种也是最常用的一种格式注意两边最少需要一个空格位
  使用echo 输出一下$? 可以看见返回值为非0通过判断的返回结果我们可以断定cdrom这个目录是不存在的。
  [root@RHEL7 shell]# mkdir /media/cdrom
  [root@RHEL7 shell]# [ -d /media/cdrom/ ]
  [root@RHEL7 shell]# echo $?
  0
  当我将cdrom这个目录创建完成之后在进行判断就是条件成立返回值为0
  这个表达式是成立的。
  通过查看变量$?的方式比较不直观我们可以使用逻辑测试中的&来进行判断
  [root@RHEL7 shell]# [ -d /media/cdrom/ ]&& echo "YES"
  YES
  [root@RHEL7 shell]# [ -d /media/cd/ ]&& echo "YES"
  [root@RHEL7 shell]# echo $?
  1
  在表达式的后面执行 双&
  如果前面的表达式成立则输出YES否则什么都不输出
  逻辑测试我们之后会讲
  以上就是文件测试的内容这些内容在写脚本的时候我们都会使用
  很关键,脚本是否执行就是看判断的结果


运维网声明 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-557204-1-1.html 上篇帖子: apache服务自动化安装_shell脚本 下篇帖子: shell脚本的调试
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

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

扫描微信二维码查看详情

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


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


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


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



合作伙伴: 青云cloud

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