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

Shell脚本编程小结

[复制链接]

尚未签到

发表于 2018-8-29 06:16:29 | 显示全部楼层 |阅读模式
  1、  描述shell程序的运行原理:
  Shell是一种具备特殊功能的程序,它提供了用户与内核进行交互操作的一种接口.它接收用户输入的命令,并把它送入内核去执行.内核是Linux系统的心脏,从开机自检时就驻留在计算机的内存中,直到计算机关闭为止,而用户的应用程序存储在计算机的硬盘上,仅当需要时才被调入内存.Shell是一种应用程序,当用户登录Linux系统时,Shell就会被调入内存执行.Shell独立于内核,它是连接内核和应用程序的桥梁,并由输入设备读取命令,再将其转为计算机可以理解的机械码,Linux内核才能执行该命令。
  图1-1描述了Shell在Linux系统中的位置
DSC0000.jpg

  Shell脚本是把命令堆砌在一起,shell通过词法分析,语法分析,语义分析,按顺序、选择或循环执行脚本中的命令。脚本运行结束,此Shell进程也即终止
  2、  Shell脚本编程总结
  变量:所谓变量就是可变化的量,命名内存空间,本质就是存储数据的一个或多个计算机内存地址。
  bash环境:
  本地变量:当前shell进程;
  环境变量:当前shell进程及其子进程;
  局部变量:某个函数执行过程;
  位置参数变量:在脚本中引用传递给脚本的参数;在函数中引用传递给函数的参数;
  特殊变量:
  $$:当前shell的进程号。对于shell脚本,这是其正在执行时的进程ID
  $!:前一个后台命令的进程号
  $?:前一个命令执行后的返回值,0表示没有错误,非0表示有错误
  $-:当前命令的引导符
  $_:上条命令的执行结果
  $*:所有参数列表。如"$*"用「"」括起来的情况、以"$1$2 … $n"的形式输            出所有参数。
  $@:所有参数列表。如"$@"用「"」括起来的情况、以"$1""$2" … "$n" 的            形式输出所有参数。
  $#:传递到脚本的参数数量
  $0:正在被执行命令的名字。对于shell脚本而言,这是被激活命令的路径
  $1~$n:该变量与脚本被激活时所带的参数相对应。n是正整数,与参数位置                    相对应。
  示例:编写一个位置参数的position.sh脚本
        #!/bin/bash  
        echo"The script name is : $0"   #$0表示脚本本身
  
        echo  "Parameter #1: $1"
  
        echo  "Parameter #2: $2"
  
        echo  "Parameter #3: $3"
  
        echo  "Parameter #4: $4"
  
        echo  "Parameter #5: $5"
  
        echo  "Parameter #6: $6"
  
        echo  "Parameter #7: $7"
  
        echo  "Parameter #8: $8"
  
        echo  "Parameter #9: $9"
  
        echo  "Parameter #10: $10"
  

  
        echo"--------------------"
  
        echo"All the command line parameters are: $*"
  
        #$*和$@一样,表示从$1开始的全部参数
DSC0001.jpg

  变量类型:
  变量类型的作用:存储空间、运算、存储格式
  数值,字符;
  数值:整数、浮点数;
  字符:ASCII
  语言对变量类型的支持力度:
  强类型:一种总是强制类型定义的语言,要求变量的使用要严格符合定义,所有变量都必须先定义后使用。java、.NET、C++等都是强制类型定义的。也就是说,一旦一个变量被指定了某个数据类型,如果不经过强制转换,那么它就永远是这个数据类型了;
  弱类型:与强类型相反。故变量类型不严格区分;
  默认存储机制:bash为字符;
  bash的变量使用特点:弱类型、无须事先声明;
  本地变量:
  本地变量命名:
  变量名=变量值;
  变量名:只能包含数字、字母和下划线;且不能以数字开头;不能超过20个字符;
  =:赋值符号;
  变量值:我们需要给变量名赋予的值;
  注意:在变量、等号和值之间不能出现空格。
  引用:
  弱引用: ""双引号, 其内部的变量引用会被替换为变量值;
  强引用:''单引号,其变量的变量引用会保持原有字符;
  命令引用:`COMMAND`反引号, 也可使用$(COMMAND),引用命令的执行结果;
  声明为整型:
  declare -i name[=value]
  let name=value
  查看所有本地变量:set命令
DSC0002.jpg

  变量的生命周期:
  创建
  销毁:
  自动销毁:shell进程终止;
  手动销毁:unset name
  环境变量:
  被“导出”的本地变量
  export name[=value]
  declare -x name[=value]
  查看所有环境变量:env,printenv, export
DSC0003.jpg

  shell脚本:其实就是纯文本文件,我们可以编辑这个档案,然后让这个文本文件来帮我们一次执行多个指令,或者是利用一些运算与逻辑判断来帮我们达成某些功能启动脚本。
  (1)bash 脚本名
  (2)给脚本一个执行权限即可直接通过脚本路径运行脚本。
  # ./PATH/TO/SCRIPT_FILE。
  Shell脚本通常是以#!起始的文本文件,如“#!/bin/bash”,这行被称为shebang,指定了解释此脚本shell的路径,执行脚本时系统会调用这个shell来运行此脚本。字符#指明注释的开始。注释部分以#为起始,一直延续到行尾,注释行通常用于为代码提供注释信息,或者用于暂停执行某行代码,会被解释器忽略。
  bash的常用选项:
  -n: 检查脚本中的语法错误;
  -x:调试执行脚本;
  当我们需要查看脚本是否执行成功,可以在执行脚本以后可以使用 $? 命令查看上一条命令执行状态结果:
  0: 成功
  1-255:失败
  我们也可在脚本中自定义脚本的状态结果:
  在脚本中敲入命令exit [n]:n为我们想要输出的数字
  注意:脚本中任何位置执行了exit命令即会终止当前shell进程;
  条件测试:
  界定程序执行环境;
  (1) 根据运行的命令的状态结果;
  (2) 测试表达式: EXPR 表达式
  test EXPRESSION
  [ EXPRESSION ]
  ` EXPRESSION `
  整数测试:隐含着做数值大小比较,所以不要给变量引用加引用;
  $A -gt $B:是否大于;是则为“真”,否则为“假”;
  $A -ge $B: 是否大于等于;
  $A -lt $B:是否小于;
  $A -le $B: 是否小于等于;
  $A -eq $B: 是否等于;
  $A -ne $B:是否不等于;
  字符串测试:ASCII数值越大,字符比较时其值越大;
  "$A" > "$B":是否大于;
  "$A" < "$B":是否小于;
  "$A" == "$B":是否等于;
  "$A" != "$B":是否不等于;
  -z "$A":是否为空;空则为“真”,否则为“假”
  -n "$A":是否不空;不空则“真”,空则为“假”
  注意:应该使用` EXPRESSION`
  文件测试:测试文件的存在性以及属性;
  -e $file: 是否存在;存在则为“真”,否则为“假”;
  -f $file:文件是否存在且为普通文件;
  -d $file:文件是否存在且为目录;
  -h $file:是否存在且为符号链接文件;
  -b $file:是否存在且为块设备文件;
  -c $file:是否存在且为字符设备文件;
  -S $file:是否存在且为套接字文件;
  -p $file: 是否存在且为管道文件;
  -r $file: 当前用户对文件是否拥有读权限;
  -w $file:当前用户对文件是否拥有写权限;
  -x $file:当前用户对文件是否拥有执行权限;
  -u $file:文件是否拥有SUID权限;
  -g $file:文件是否拥有SGID权限;
  -k $file:文件是否拥有sticky权限;
  -O $file: 当前用户是否为指定文件的属主;
  -G $file: 当前用户是否为指定文件的属组;
  双目操作符:
  $file1 -nt$file2: file1是否新于file2, file1的最近一次的修改时间戳是否晚于file2的;
  $file1 -ot$file2: file1是否旧于file2, file1的最近一次的修改时间戳是否早于file2的;
  $file1 -ef$file2:file1与file2是否指向了同一个inode,测试二者是否为同一个文件的硬链接;
  特殊设备:
  /dev/null: 空,bit buckets,吞下所有数据,并直接丢弃;
  /dev/zero:吐出一堆0;
  bash之条件判断(选择执行):
  if/then ;case
  if CONDITION; then
  if-true-分支
  fi
  if CONDITION; then
  if-true-分支
  else
  if-false-分支
  fi
  ! CONDITION: 表示的是取反
  脚本参数(位置参数变量):
  # ./name.sh  /etc/fstab /etc/grub.conf
  $0        $1         $2
  参数$0—>shell自身文件,$1—>shell中定义的第一个参数,$2—>shell中定义的第二个参数,以此类推。
  特殊变量:
  $?: 命令的状态结果;
  $#: 传递给脚本或函数的参数的个数;
  $*和$@: 引用传递给脚本或函数的参数列表;
  与用户交互:
  read命令:
  read [options] VAR...
  -p"PROMPT"
  -t timeout
  示例:-t5 5秒后超时退出交互。
            #!/bin/bash  
            #
  
            read -p "Plz enter ausername: " -t 5 username
  
            if [ -z "$username"]; then
  
               username="myuser"
  
            fi
  
            if id $username &>/dev/null; then
  
               echo "$username exists."
  
            else
  
               useradd $username
  
            fi
  命令引用:
  `COMMAND`, $(COMMAND)
  引用命令的执行结果;
  (1)ls `which cat`
DSC0004.jpg

  (2) lines=$(wc -l /etc/fstab | cut -d'' -f1)
DSC0005.jpg

  循环语句:循环就是通过循环编程对循环体进行多次运行,直到结果匹配给定的退出循环条件。
  Shell中的循环语句:for,while, until
  VARIABLE 定义的变量
  for VARIABLE in LIST; do
  循环体
  done
  LIST:是由一个或多个空格或换行符分隔开的字符串组成;即可使用LIST 给一个变量进行多次逐个赋值;LIST 不为空时进入循环,LIST逐个赋值直到最后一个结束后循环结束,即退出循环;
  for username in user1 user2user3; do
  循环体
  done
  示例:
  添加10个用户,user1-user10;
            #!/bin/bash  
            #
  
            for username in user1 user2 user3 user4 user5; do
  
            if id $username &> /dev/null; then
  
            echo "$username exists."
  
            else
  
            useradd $username
  
            echo "Add user $username finished."
  
            fi
  
            done
  LIST的生成方法:
  (1) 整数列表
  (a) {start..end}
  (b) $(seq [start `step` end)
  (2) 直接给出列表
  (3) glob
  (4) 命令生成
  示例:数值列表
            #!/bin/bash  
            #
  
            for i in {1..10}; do
  
            if id user$i &> /dev/null; then
  
            echo "user$i exists."
  
            else
  
            useradd user$i
  
            echo "Add user user$i finished."
  
            fi
  
            done
  示例:glob,即定义参数变量为绝对路径下的文件:
            #!/bin/bash  
            #
  
            for filename in /var/log/*; do
  
            file $filename
  
            done
  示例:命令生成列表
            #!/bin/bash  
            #
  
            for username in $(cut -d: -f1/etc/passwd); do
  
            echo "$usernameprimary group: $(id -n -g $username)."
  
            done
  Shell脚本中的算术运算:
  +, -, *, /, %, **
  (1) $[$A+$B]
  (2) $(($A+$B))
  (3) let VARIABLE=$A+$B
  (4) VARIABLE=$(expr $A + $B)
  示例:求100以内所以正整数之和;
            #!/bin/bash  
            #
  
            declare -i sum=0
  
            for i in {1..100}; do
  
               sum=$[$sum+$i]
  
            done
  
            echo $sum
  增强型赋值:
  +=
  sum=$[$sum+$i]可写为:letsum+=$i
  -=, *=, /=, %=
  let count=$[$count+1]   --> let count+=1 --> let count++
  let count=$[$count-1]  --> let count-=1 --> let count--
  示例:显示/etc目录下所有普通文件列表,而后统计一共有多少个文件;
  测试表达式:
  整数测试:-gt,-lt, -ge, -le, -eq, -ne
  字符串测试:==,>, 比较命令hostname的结果是否为localhost;
  (2) 模式匹配测试:[["STRING" =~ PATTERN ]]
  组合测试条件:
  条件间逻辑运算:
  与:多个条件要同时满足;
  或:多个条件满足其一即可;
  非:对指定的条件取反;
  表达式组合:
  与:` CONDITION1 -aCONDITION2 `
  或:` CONDITION1 -oCONDITION2 `
  非:[ ! CONDITION ]
  命令组合:
  与:COMMAND1 &&COMMAND2   /dev/null; then
  
                    echo "$username is logged."
  
                    break
  
                else
  
                    let count++
  
                    echo "$count $username is not login."
  
            fi
  
                sleep 3
  
            done
            #!/bin/bash  
            #
  
            declare -i count=0
  
            username=$1
  
            if [ $# -lt 1 ]; then
  
                echo "At lease one argument."
  
                exit 1
  
            fi
  
            if ! id $username &> /dev/null; then
  
                echo "No such user."
  
                exit 2
  
            fi
  
            until who | grep "^$username" &> /dev/null; do
  
                let count++
  
                echo "$count $username is not login."
  
                sleep 3
  
            done
  
            echo "$username is logged on."
  while循环的特殊用法:
  遍历文件的每一行:
  while read VARIABLE;do
  循环体
  done

运维网声明 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-557850-1-1.html 上篇帖子: shell 函数的简单用法 下篇帖子: linux学习之shell的流程控制
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

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

扫描微信二维码查看详情

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


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


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


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



合作伙伴: 青云cloud

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