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

第七章,shell编程基础

[复制链接]

尚未签到

发表于 2018-8-20 10:06:39 | 显示全部楼层 |阅读模式
  更多笔记点击查看
  Linux学习从入门到打死也不放弃,完全笔记整理(持续更新)
  http://blog.51cto.com/13683480/2095439
  笔记整理开始时间:2018年4月12日11:37:35
  本章内容:
  编程基础
  脚本基本格式
  变量
  运算
  条件测试
  配置用户环境
  编程基础:
  程序:指令+数据
  程序编程风格:
  过程式:以指令为中心,数据服务于指令
  面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤
  一步一步实现,使用的时候一个一个依次调用就可以了
  对象式:以数据为中心,指令服务于数据
  面向对象是把构成问题事务分解成各个对象,建立对象的目的不是为
  了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为
  shell程序:提供了编程能力,解释执行
  是对一堆Linux命令的逻辑化处理
  程序的的执行方法:
  计算机:运行二进制指令
  编程语言:
  低级:汇编
  高级:
  编译:高级语言-->编译器-->目标代码
  在编译时将代码转换成2进制
  java,c#
  解释:高级语言-->解释器-->机器代码
  在程序执行时才转换成2进制
  shell,perl,python
  编程基本概念:
  编程逻辑处理方式
  顺序执行,循环执行,选择执行
  shell编程:过程式,解释执行
  编程语言的基本结构:
  各种系统命令的组合
  数据存储:变量、数组
  表达式:a + b
  语句:if
  shell脚本基础:
  shell脚本:
  包含一些命令或声明,并符合一定格式的文本文件
  格式要求:首行shebang机制
  #!/bin/bash                          shell
  #!/usr/bin/python        python
  #!/usr/bin/perl                    perl
  shell脚本的用途有:
  自动化常用命令
  执行系统管理和故障排除
  创建简单的应用程序
  处理文本或文件
  创建shell脚本:
  第一步:使用文本编辑器来创建文本文件
  第一行必须包括shell声明序列:#!
  #!/bin/bash
  添加注释
  注释以#开头
  第二步:运行脚本
  给予执行权限,+x,在命令行上指定脚本的绝对或相对路径
  /root/hello
  直接运行解释器(bash),如:
  bash  /root/hello
  cat ff115  |bash
  PS:source 执行程序  表示脚本会在当前shell运行不开启子进程
  脚本规范:
  1.第一行一般为调用使用的语言
  2.程序名,避免更改文件名为无法,正确找到的文件
  (如不要取名bash,或者其他存在的程序名)
  3.版本号
  4.更改后的时间
  5.作者相关信息
  6.该程序的作用。以及注意事项
  7.最后是各版本的更新简要说明
  脚本基本结构
  #!shebang
  configuration_variables        配置变量
  function_definitions              定义函数
  main code                                  主要代码
  脚本调试:
  检测脚本中的语法错误
  bash -n hello.world
  如:
  [root@sentos7 ~/bin]#bash -n ceshi
  ceshi: line 2: unexpected  EOF while looking for matching `"'
  ceshi: line 7: syntax  error: unexpected end of file
  调试执行:
  bash -x hello.world
  PS:
  bash -n 只检查语法错误
  如果是语法错误后续命令不执行
  如果是命令not found 后续会继续执行
  bash -x  +代表深度,直接执行+,被调用执行++
  脚本内不支持别名,也无法添加别名
  变量:命名的内存空间
  数据存储方式:
  把程序中准备使用的数据赋给一个简短、易于记忆的名字
  类型:
  字符型
  数值:×××,浮点型
  作用:
  数据存储
  参与运算
  表示数据范围
  强类型:
  变量不经过强制转换,它永远是这个数据类型,不允许隐式的类型转化。一般
  定义变量时必须指定类型,参与运算必须符合类型要求;调用未声明变量会
  产生错误。
  如jave c#
  弱类型:
  语言的运行时会隐式做数据类型转换。无须指定类型,默认均为字符型,参
  与运算会自动进行隐式类型转换,变量无须事先定义可直接调用
  如:bash不支持浮点数, php
  变量命名法则:
  1.不能使用程序中的保留字;例如:if ,for
  2.只能使用数字、字母及下划线,且不能以数字开头
  3.见名知义
  4.统一命名规则:驼峰命名法
  bash中变量的种类:
  根据变量的生效范围等标准等标准划分下面变量类型:
  局部变量:
  生效范围为当前shell进程;对当前shell之外的其他shell进程,
  包括当前shell的子shell进程均无效
  环境(全局)变量:
  生效范围为当前shell进程及其子进程
  本地变量:生效范围为当前shell进程中某代码片段,通常指函数
  位置变量:$1,$2,..${10}..来表示,用于让脚本在脚本代码中调用通过命令行传递
  给它的参数
  特殊变量:
  $?,$0,$*,$@,$#,$$
  $?           前一个命令的退出状态,成功为0,不成功为非0
  局部变量:
  变量赋值:name='value'
  可以使用引用value:
  1.可以是直接字串;     name=‘root’
  2.变量引用:         name=$USER
  3.命令引用:         name=`command`
  name=$(cmd)
  ps:
  变量一旦赋值,除非重新赋值,否则所占内存空间不变,值不变
  name1=name2的情况
  就算赋值之后name2的值改变了,name1的值保持不变
  i=100      赋值为字符,不问数字类型
  变量引用:
  ${name}  $name
  "":弱引用,其中的变量引用会被替换为变量值,如
  [root@sentos7  ~/bin]#echo "$PS1"
  \[\e[1;35m\][\u@\h \w]\$\[\e[0m\]
  '':强引用,其中的变量引用不会被替换为变量值,而保持原字符串
  [root@sentos7  ~/bin]#echo '$PS1'
  $PS1
  显示已经定义的所有变量:set
  删除变量:     unset name
  PS:
  pstree -p        进程tree
  echo $$  当前进程的进程编号
  echo $PPID 父进程的进程编号
  练习1
      1、编写脚本/root/bin/systeminfo.sh,显示当前主机系统信息,包括主机名,
  IPv4地址,操作系统版本,内核版本,CPU型号,内存大小,硬盘大小
      2、编写脚本/root/bin/backup.sh,可实现每日将/etc/目录备份到
  /root/etcYYYY-mm-dd中
      3、编写脚本/root/bin/disk.sh,显示当前硬盘分区中空间利用率最大的值
      4、编写脚本/root/bin/links.sh,显示正连接本主机的每个远程主机的IPv4地址
  和连接数,并按连接数从大到小排序
  环境变量:
  变量声明,赋值:
  export name=Value             相当于name=Value;export  name
  declare -x name2=Value
  let  c=name+name2;export c
  变量引用:$name,${name2}
  显示所有环境变量:
  env
  printenv
  export
  declare -x
  删除变量:
  unset name
  bash内建的环境变量:
  PATH:
  SHELL:
  USER:
  UID:
  HOME:
  PWD:
  SHLVL:          当前shell层数
  LANG:            语言键盘、字符编码
  MAIL:           当前用户mail目录
  HOSTNAME:
  HISTSIZE:
  _:                    前一个命令的最后一个参数
  只读和位置变量:
  只读变量:只能声明,但不能修改和删除
  声明只读变量:
  readonly  name
  declare -r  name
  查看只读变量:
  readonly  -p
  位置变量:再脚本代码中调用通过命令行传递给脚本的参数
  $1,$2,..${10}..:   对应相应第1,2..10..个参数
  脚本中命令:shift[n] 可以传递参数位置,如:
  shift              可以将原本$2,变成$1
  shift 3            将原$4变成$1
  $0    命令本身,名字
  默认带路径,可以用 `basename $0`取出来
  $0  如果是软链接的话 $0会显示各自软链接的名字
  $*     传递给脚本的所有参数,全部参数合为一个字符串
  $@   传递给脚本的所有参数,每个参数为独立字符串
  $#   传递给脚本的参数的个数
  $@ $*    在脚本调用脚本传递参数时,如果用"$*",会将所有参数当成一个
  字符串传递
  $* $@  "$@"   会将每个参数单独传递
  set --     清空所有位置变量
  退出状态
  进程使用退出状态来报告成功或失败
  $?            保存最近的命令退出状态
  0            成功
  1-255     失败
  例如:
  ping -c1 172.20.3.14 &>/dev/null
  echo $?
  退出状态码:
  bash 自定义退出状态码
  exit [n]    自定义退出状态码
  注意:
  脚本中一旦遇到exit命令,脚本会立即终止;终止退出状态取决于
  exit命令后面的数字
  如果没有给脚本指定退出状态码,整个脚本的退出状态码取决于脚本
  中执行的最后一条命令的状态码
  算术运算:let
  bash中的算术运算:help let
  常用算术:
  +,-,*,/,%(取模 取余),**(乘方),id++,id--,
  实现算术运算的格式:
  1.     let var=算术表达式
  let  z=x+y;let x++;let  y=x**2;
  let  z=(3*x+4*y/3)-2*x
  2.     var=$[算术表达式]
  z=$[(3*x+4*y/3)-2*x]
  3.     var=$((算术表达式))
  z=$(((3*x+4*y/3)-2*x))
  4.     var=$(expr arg1 arg2  arg3...)
  如:z=$(expr $x + $y)         表示z=x+y
  *需要写成\*
  5.     declare -i  var=数值(可以使是算式)
  declare -i  x=x+y
  declare -i  x=3*x+y*4/2
  6.     echo ’算术表达式‘ |bc
  bash有内建的随即数生成器:$RANDOM(0-32676)
  echo $[$RANDOM%50]:               0-49之间随机数
  赋值:
  增强型赋值:
  +=,-=,*=,/=,%=
  let x+=3;x-=1;x*=5;x/=4
  +3 -1  *5     /4
  shell不支持浮点计算,所以除法会有商整取余
  自增,自减
  let x+=1;let x++
  let x-=1;let x--
  练习2
  1、编写脚本/root/bin/sumid.sh,计算/etc/passwd文件中的第10个用户和第
  20用户的ID之和
       2、编写脚本/root/bin/sumspace.sh,传递两个文件路径作为参数给脚本,计
  算这两个文件中所有空白行之和
       3、编写脚本/root/bin/sumfile.sh,统计/etc, /var, /usr目录中共有多少个一级
  子目录和文件
  逻辑运算
  与:        &
  或:        |
  非:        !
  !1=0
  !0=1
  短路运算:
  cmd1 && cmd2
  如果cmd1为假,cmd2不需要执行,反之cmd1为真,需要cmd2执行
  cmd1 || cmd2
  如果cmd1为真,cmd2不需要执行,反之cmd1为假,需要cmd2执行
  cmd1 && cmd2 || cmd3    要求cmd2必真
  cmd1为真,执行cmd2
  为假,执行cmd3
  异或:^ XOR
  二进制运算,同为0 异为1
  a=5;b=6;echo $a  $b;a=$[a^b];b=$[a^b];a=$[a^b];echo $a $b
  将a  b的值互换
  ture 和false
  只返回真或者假,不做任何操作
  true && echo hello
  false   && echo hello||echo nihao
  条件测试:test
  判断某需求是否满足,需要由测试机制来实现
  专用的测试表达式需要由测试命令辅助完成测试过程
  评估布尔声明,以便用在条件性执行中
  若真        则返回0
  若假        则返回1
  测试命令:
  test expression              如:test a = b ;echo  $?
  [ $a = b ] && echo ture || echo  false
  [[ $a =~ pattern ]]
  表达式epression 前后必须有空白字符
  根据退出状态而定,命令可以有条件的执行
  && 代表条件性的and then
  ||      代表条件性的 or else
  例如:
  grep -q no_such_user /etc/passwd || echo 'NO such  user'
  id usera &>/dev/null && echo "usera is exist" || useradd  usera
  长格式的例子:
  test "$A" == "$B" && echo "Strings are  equal"
  [ "$A" == "$B" ]
  test "$A" -eq "$B" && echo "Integers are  equal"
  [ "$A" -eq "$B" ]
  bash的数值测试:
  -v var
  变量是否设置 test -v var && echo hello||echo  nihao
  [ -v var ] && set || not  set
  PS:
  此处使用变量var前不可加"$",否则判断异常
  数值测试:
  -gt 是否大于              [ $A -gt $B  ]
  -ge        是否大于等于
  -eq         是否等于
  -ne        是否不等于
  -lt           是否小于
  -le          是否小于等于
  bash的字符串测试:
  ==          是否等于                                    等于为真,0
  >            ascii码是否大于ascii码
  <                           是否小于
  !=            是否不等于                                 不等于为真,0
  =~           左侧字符串是否能够被右侧的pattern所匹配
  注意:此表达式一般用于[[ ]]中,支持扩展的正则表达式
  -z &quot;string&quot;              字符串是否为空,空为真,不空为假
  -n &quot;string&quot;             字符串是否不空,不空为真,空为假
  注意:     用于字符串比较时用到的操作数都应该使用引号
  [[ ]]使用pattern时 表达式 不能加引号 ,也不能识别\< \>  \b
  判断是否为空也可以:
  [ x = x&quot;$a&quot; ] && echo ture || echo false
  练习3:
  1、编写脚本/root/bin/argsnum.sh,接受一个文件路径作为参数;如果参数
  个数小于1,则提示用户“至少应该给一个参数”,并立即退出;如果参数个数
  不小于1,则显示第一个参数所指向的文件中的空白行数
   2、编写脚本/root/bin/hostping.sh,接受一个主机的IPv4地址做为参数,测
  试是否可连通。如果能ping通,则提示用户“该IP地址可访问”;如果不可
  ping通,则提示用户“该IP地址不可访问”
   3、编写脚本/root/bin/checkdisk.sh,检查磁盘分区空间和inode使用率,如
  果超过80%,就发广播警告空间将满
  Bash的文件测试:
  存在性测试:
  -a file            同  -e
  -e file             文件存在性测试,存在为真,否则为假
  存在性及类别测试
  -b file             是否存在且为块设备文件
  -c file              是否存在且为字符设备文件
  -d file             是否存在且为目录文件
  -f file              是否存在且为普通文件
  -h file     或 -L file        是否存在且为符号链接文件
  -p file    是否存在且为命名管道文件
  -S file             是否存在且为套接字文件
  Bash的文件权限测试:
  文件权限测试:
  -r file              是否存在且可读
  -w file             是否存在且可写
  -x file     是否存在且可执行
  文件特殊权限测试:
  -u file             是否存在且拥有suid权限
  -g file             是否存在且拥有sgid权限
  -k file     是否存在且拥有sticky权限
  Bash的文件属性测试:
  文件大小测试:
  -s file              是否存在且为空
  文件是否打开
  -t fd:fd 文件描述符是否在某终端已经打开
  -N file             文件自从上一次被读取之后是否被修改过
  -O file             当前用户是否为文件属主
  -G file             当前有效用户是否为文件属组
  双目测试:
  file1 -ef file2          file1是否是file2的硬链接
  file1 -nt file2 file1是否新于file2  (mtime)
  file1 -ot file2         file1是否旧与file2
  Bash的组合测试条件:
  第一种方式:
  cmd1 && cmd2    且
  cmd1 ||   cmd2      或
  !cmd                  非
  如:       [[  -r FILE ]] && [[ -w FILE  ]]
  第二种方式:
  [ expression1 -a expression2 ]            并且
  [ expression1 -o expression2 ]            或者
  [ !expression ]                                非
  例:
  [ -z &quot;$HOSTNAME&quot; -o &quot;$HOSTNAME&quot; == &quot;localhost.localdomain&quot; ] &&
  hostname www.magedu.com
  [ -f /bin/cat -a -x /bin/cat ] && cat  /etc/fstab
  PS:
  &&(-a)     ||(-o)可连续使用
  [ -r &quot;$1&quot; -a -w &quot;$1&quot; -a -x &quot;$1&quot; ]  && echo ture ||  false
  [ -a &quot;$1&quot;  ] && [ -r &quot;$1&quot; ] && [ -w &quot;$1&quot; ] && [ -x &quot;$1&quot; ]  && echo ture || false
  只要有一个为假,就返回假
  [ -r &quot;$1&quot; -o -w &quot;$1” -o &quot;$1&quot; ] && echo  ture || false
  [ -r &quot;$1&quot;  ] || [ -w &quot;$1&quot; ] || [ -x &quot;$1&quot;] && echo ture ||  false
  只要一个为真,则返回为真
  练习:
  1、编写脚本/bin/per.sh,判断当前用户对指定参数文件,是否不可读并且不可写
      2、编写脚本/root/bin/excute.sh ,判断参数文件是否为sh后缀的普通文件,如
  果是,添加所有人可执行权限,否则提示用户非脚本文件
      3、编写脚本/root/bin/nologin.sh和login.sh,实现禁止和充许普通用户登录系统
  read:
  使用read来把输入值分配给一个或多个shell变量
  -p                  指定要显示的提示,如:
  read -p  &quot;Please input your name: &quot; name
  -s                  静默输入,一般用于密码,如:
  read -s -p  &quot;Please input your password: &quot; passw
  -n N               指定输入的字符长度N
  指定长度之后,如达到长度,后续指令不会换行,直接在输入的内容之后显示了
  想要达到换行的目的,需要下一行加上
  echo  &quot;&quot;   但是如果手动回车则会显示一行空行
  -d '字符' 输入结束符     到此字符直接结束输入

  read -t 20 -n  20 -p &quot;Please input you>  与-n类似,也是不会换行
  -t N        TIMEOUT为N秒
  timeout并不会退出脚本,而是会执行后续指令
  read        如果从标准输入中读取值,给每个单词分配一个变量
  所有剩余单词都被分配给最后一个变量
  不支持管道接受标准输入     | read name
  bash如何展开命令行
  把命令行分成单个命令词
  展开别名
  展开大括号的声明({})
  展开波浪符声明(~)
  命令替换$()和(``)
  再次吧命令行分成命令词
  展开文件通配(*、?、[abc]等等)
  准备I/O重导向()
  运行命令
  防止扩展:
  反斜线 \ 会使随后的字符按原意解释
  $     echo your cost:\$5.00
  your cost:$5.00
  加引号来防止扩展
  单引号''   防止所有扩展
  双引号&quot;&quot; 也防止所有扩展,但是以下情况例外
  $                   --变量扩展
  `` $()        --命令替换
  \                    --禁止单个字符扩展
  !                   --历史命令替换
  bash的配置文件:
  按生效范围划分、存在两类
  全局配置:
  /etc/profile
  /etc/profile.d/*.sh
  /etc/bashrc
  个人配置:
  ~/.bash_profile
  ~/.bashrc
  shell登录两种方式
  交互式登录:
  1)直接通过终端输入账号密码登录
  2)使用 su - username 切换的用户
  执行顺序:
  /etc/profile -->  /etc/profile.d/*.sh --> ~/.bash_profile -->
  ~/.bashrc -->  /etc/bashrc
  非交互式登录:
  1)su username
  2)图形界面下打开的终端
  3)执行脚本
  4)任何其他的bash实例
  执行顺序:~/.bashrc -->  /etc/bashrc --> /etc/profile.d/*.sh
  按功能划分:
  profile类:
  为交互式登录的shell提供配置
  全局:/etc/profile,  /etc/profile.d/*.sh
  个人:~/.bash_profile
  功能:
  用于定义环境变量
  运行命令或脚本
  bashrc类:
  为交互式和非交互式登录的shell提供配置
  全局:/etc/bashrc
  个人:~/.bashrc
  功能:
  定义命令别名和函数
  定义本地变量
  配置文件修改生效:
  修改profile和bashrc文件后需生效
  两种方法:
  重新启动shell进程(重新登录)
  . 或  source
  例如:  . ~/.bashrc
  Bash退出任务:
  保存在~/.bash_logout文件中
  在退出登录shell时运行
  用于:
  创建自动备份
  清楚临时文件
  变量:$-
  h:hashall,打开这个选项后,shell
  会将命令所在的路径hash下来,避免每次都要查询。通过set+h将h选项关闭
  i:interactive-comments,包含这个选项说明当前的shell是一个交互式的shell
  所谓的交互式shell,在脚本中,i选项都是关闭的
  m:monitor,打开监控模式,就可以通过job  control来控制进程的停止、继续、
  后台或者前台执行等。
  B:braceexpand,大括号扩展
  H:history,H选项打开,可以展开历史列表中的命令,可以通过!来完成,
  例如!!,返回最近的一个历史命令,!n  返回第n个历史命令
  练习:
  1、让所有用户的PATH环境变量的值多出一个路径,例如:
  /usr/local/apache/bin
      2、用户root登录时,将命令指示符变成红色,并自动启用如下别名:
  rm=‘rm –i’
  cdnet=‘cd  /etc/sysconfig/network-scripts/’
  editnet=‘vim  /etc/sysconfig/network-scripts/ifcfg-eth0’
  editnet=‘vim /etc/sysconfig/network-scripts/ifcfg-eno16777736  或 ifcfg-ens33 ’ (如果系
  统是CentOS7)
      3、任意用户登录系统时,显示红色字体的警示提醒信息“Hi,dangerous!”
      4、编写生成脚本基本格式的脚本,包括作者,联系方式,版本,时间,描述等
      5、编写用户的环境初始化脚本reset.sh,包括别名,登录提示符,vim的设置,
  环境变量等
  笔记整理完成时间:2018年4月13日16:58:39


运维网声明 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-554143-1-1.html 上篇帖子: shell介绍,history,别名,通配符及重定向 下篇帖子: Linux Shell编程之基本概念
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

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

扫描微信二维码查看详情

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


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


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


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



合作伙伴: 青云cloud

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