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

Bash Shell脚本编程-变量知识

[复制链接]

尚未签到

发表于 2018-8-21 09:31:38 | 显示全部楼层 |阅读模式
  Shell:GUI  CLI
  提供交互式接口:提高效率
  命令行展开:~ ,{}
  命令别名:alias
  命令历史:history
  Globbing:*,?,[],[^]
  命令补全:$PATH指定的目录下
  路径补全:TAB键
  管道:|
  输入输出重定向:>    >>
  提供编程环境:
  bash自动运行脚本机制
  面向过程(以指令为中心组织数据)的编程模型
  脚本编程
  输入指令解决问题
  程序是语句和表达式组成的
  运行时根据一定流程来执行:
  顺序执行
  选择执行
  循环执行
  程序是指令+数据的
  面向对象(以数据为中心来组织指令)
  框架组织程序中的各个指令
  程序运行模型:
  编译运行:
  源程序——>预处理——>编译——>汇编——>链接——>运行
# file /bin/cat  /bin/cat: ELF 64-bit LSB executable, x86-64, version 1 (SYSV),
  dynamically linked (uses shared libs), for GNU/Linux 2.6.18, stripped
  # ldd /bin/cat         链接到的库
linux-vdso.so.1 =>  (0x00007fff5c3ff000)  libc.so.6 => /lib64/libc.so.6 (0x00000035d0e00000)
  /lib64/ld-linux-x86-64.so.2 (0x00000035d0600000)
  解释运行:
  向内核提出运行要求时是解释器运行成进程
  源程序——>无需编译——>解释器——>内核根据文件的格式来判定可执行(脚本的第一行要写入shebang,如#!/bin/bash)——>让bash程序来执行
  变量:命名的内存空间
  变量名:存放在内存中,由解释器和内存自行维护
  变量值:存放在内存中,由用户来维护
  数据类型:127:01111111    7bit存储空间
  127:1,2,7,是字串,要24位来存储
  ASCII码:0-9,a-z,A-Z,punction
  0-127 ,128种变化,要7位就能存储
  0000   0000 - 0111 1111
  1.定义了数据存储格式
  2.定义了数据表示范围
  3.定义数据可以参与的运算类型
  强类型编程语言:严格区分类型
  弱类型编程语言:不严格区分类型
  bash:把所有值都默认当作字符存储
  类型:
  数值型:
  精确数值型:整数
  近似数值型:float(单精度浮点),double(双精度浮点)
  计算机里面有专门的浮点单元来进行
  浮点数的存储格式?
  字符型:
  单个字符,字符串string
  布尔型:
  true,false
  逻辑运算:
  与:1&&1=1
  1&&0=0
  0&&1=0
  0&&0=0
  或:
  1 || 1 =1
  1 || 0 =1
  0 || 1 =1
  0 || 0 =0
  非:
  !1 =0
  !0 =1
  异或:
  1 异或 1 =0
  1 异或 0 =1
  bash的变量类型:
  本地变量:只对当前shell进程有效,对当前之外的其他shell等shell都无效。
  环境变量:对当前shell进程及其子shell进程有效,对其他shell无效。
  局部变量:仅对当前shell进程中的某段代码空间内有效,通常用于函数本地程序。
  位置变量:$1  , $2   ,。。。
  特殊变量:$?,$0 ,$$ ,$# ,$* , $@
  $# 传递到脚本的参数个数
  $* 传递到脚本的参数,与位置变量不同,此选项参数可超过9个
  $$ 脚本运行时当前进程的ID号,常用作临时变量的后缀,如 haison.$$
  $! 后台运行的(&)最后一个进程的ID号
  $@ 与$#相同,使用时加引号,并在引号中返回参数个数
  $- 上一个命令的最后一个参数
  $? 最后命令的退出状态,0表示没有错误,其他任何值表明有错误
  本地变量:只是在用户当前shell生存期的脚本中使用
  无需事先声明可直接使用
  变量赋值:# VAR_NAME=
  变量引用:#echo "${VAR_NAME}"
[root@localhostretry]# a=1  
[root@localhostretry]# echo "a=$a"
  
a=1
  
[root@localhostretry]# b='2'
  
[root@localhostretry]# echo "b=$b"
  
b=2
  
[root@localhostretry]# c="3"
  
[root@localhostretry]# echo "c=${c}"
  
c=3
  
[root@localhostretry]# a=1-$a
  
[root@localhostretry]# echo "a=$a"
  
a=1-1
  
[root@localhostretry]# b='2-$a'
  
[root@localhostretry]# echo "b=$b"
  
b=2-$a
  
[root@localhostretry]# c="3-$a"
  
[root@localhostretry]# echo "c=${c}"
  
c=3-1-1
DSC0000.jpg

#echo $username  

  
#username=jerry
  
#echo $username
  
jerry
  
# echo '$username'         强引用,其中变量会被替换,所见所得
  
$username
  
# echo "$username"        弱引用,其中变量不会被替换
  
jerry
  
#set                                   显示本地变量
  
#unset VAR_NAME        撤销变量
  
#username=slackware
  
#useradd $username
  
#echo $username |passwd --stdin $username
  
Changingpassword for user slackware.
  
passwd:all authentication tokens updated successfully.
  注意习惯:
  1.数字不加引号,其他默认加双引号
  2.把命令作为变量:反引号
  CMD=`ls`
  3.${WEEK}day  若变量和其他字符组成新的变量就必须给变量加上大括号。
  4.养成将所有字符串变量用双引号括起来的使用习惯,将会减少很多编程中遇到的错误。如 "$A" 或 "${A}"
  特殊例子:awk调用shell变量引号例子
[root@localhostretry]# NUM=123  
[root@localhostretry]# awk 'BEGIN {print '$NUM'}'
  
123
  
[root@localhostretry]# awk 'BEGIN {print "$NUM"}'
  
$NUM
  环境变量:
  环境变量用于定义shell的运行环境,保证shell命令的正确执行,shell通过环境变量确定登录用户名,命令路径,终端类型,登录目录等,所有的环境变量都是系统全局变量,可用于所有子进程。
  无需事先声明
  $USER
  $HOME
  $UID
  $SHELL
  $PATH
  变量赋值:
  #export VAR_NAME=VALUE
  #declare -x  VAR_NAME=VALUE
  变量引用:${VAR_NAME}
  注意:bash内建了许多环境变量
  显示环境变量
  #export
  #printenv
  #env
  #export username        导出为环境变量
  #unset VAR_NAME        撤销变量临时生效
  变量只读:
  readonly  VAR_NAME
  declare -r VAR_NAME
  退出当前shell进程可撤销
  变量命名规则:
  1.不能使用程序中的关键字
  2.只能使用数字,字母或者下划线,而且不能以数字开头
  3.见名知意:username,userName,_
  自定义环境变量生成环境JAVA环境配置实例:tomcat,resin,csvn,hadoop
export JAVA_HOME=/application/jdk  
export CLASSPATH=$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib
  
export PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH:$HOME/bin
  
export RESIN_HOME=/application/resin
  常见放在: /etc/profile   或者 /etc/
  位置变量:
  #scirpt1.sharg1 arg2…
  $0,$1…${10}
  算术运算:
  letVAR=expression
  $[epression]
  $((epression))
  'expr arg1 arg2 arg3'
  计算整数之和
        #vi test.sh  
        #!/bin/bash
  
        #author:test
  
        declare -i sum=0
  
        sum=$[$1+$2]
  
        echo "the sum of $1 and $2:$[$1+$2]
  
        echo "the minus of $1 and $2:$[$1-$2]
  参数变量的轮替:
  shift [n]
        #vi test2.sh  
        #!/bin/bash
  
        #author:test
  
        #echo $1
  
        shift
  
        #echo $1
  
        shift
  
        #echo $1
  
        shift
  特殊变量:
  $0:获取当前执行的shell脚本的文件名,包括路径
        #cat 14.sh  
        dirname $0
  
        basename $0
  
        #sh /root/14.sh
  
        /root
  
        14.sh
  $n:获取当前执行的shell脚本的第n个参数值,n=1..9,当n为0时表示脚本的文件名,如果n大于9后,用大括号括起来${10}
        #seq 7 |sed 's#[0-9]#$&#g'  
        #cat 13.sh
  
        #!/bin/bash
  
        echo$1 $2 $3 $4 $5 $6 $7 $8 $9 $10
  
        #sh 13.sh 1 2 3
  
        12 3 10
  $#:获取当前shell命令行参数的总个数
        #cat 13.sh  
        #!/bin/bash
  
        echo$1 $2 $3 $4 $5 $6 $7 $8 $9 $10
  
        echo$#
  
        #sh 13.sh 1 2 3 4 5
  
        12 3 4 5 10
  
        5
  

  
        #sh 13.sh "1 2 3 45"
  
        12 3 4 5 1 2 3 4 50
  
        1
  $@:这个程序的所有参数"$1" "$2"  "$3"  … ,这是将参数传递给其他程序的最佳方式,因为它会保留所有内嵌在每个参数里面的任何空白。
  $*:获取当前shell的所有参数,将所有的命令行参数视为单个字符串,相当于"$!$2$3"…
        echo 'total $#'  
        echo -e '$@\n'
  
        echo -e '$*\n'
  进程状态变量:
  $$:获取当前shell的进程号PID
        #!/bin/bash  
        echo$$ >/root/pid.log
  
        whiletrue ; do
  
                uptime &>/dev/null
  
                sleep 2
  
        done
  
        #sh 15.sh &
  
        [1]3158
  
        #cat pid.log
  
        3158
  $!:获取上一个指令的PID
  $?:获取执行的上一个指令的状态码(0为成功,非0失败)
  例如:编译安装程序时,make后查询成功与否
  make
  echo $?
  打包时也可以使用
  $?返回值参考:
  0:表示运行成功
  2:权限拒绝
  1-125:表示运行识别,脚本命令,系统命令错误或参数传递错误
  126:找到命令,但无法执行
  127:未找到要运行的命令
  >128:命令被系统强制结束
  $_ :在此之前执行的命令或脚本的最后一个参数
DSC0001.jpg

  练习:写一个脚本,能接受一个参数,此参数用于用户名
  1.创建此用户
  2.给用户添加密码,密码同用户名
    #!/bin/bash  
    #author:test
  
    useradd$1
  
    echo$1 |passwd --stdin $1
  练习:写一个脚本,能接受一个参数,此参数为系统上某文本文件路径
  1.显示此文件的总行数
  2.统计此文件中的空白行数
    #!/bin/bash  
    wc-l $1 |cut -d' ' -f1
  
    grep'^[[:space:]]$' $1 |wc -l
  $*和$@的区别:
  $*:将所有命令行所有参数视为单个字符,等同于"$1$2$3"
  $@:将命令行每个参数视为单独的字符串,等同于"$!" "$2"  $3" ,这是将参数传递给其他程序的最佳方式,因为它会保留所有内嵌在每个参数里的任何空白。
    [root@localhost ~]# set -- "how old " are you.      传入3个参数  
    [root@localhost ~]# echo $#                         现在有三个参数
  
    3
  
    [root@localhost ~]# for i in $* ; do echo $i ; done循环打印参数,用$*,
  
    how
  
    old
  
    are
  
    you.
  
    [root@localhost ~]# for i in $@ ; do echo $i ; done没有双引号情况
  
    how
  
    old
  
    are
  
    you.
  
    [root@localhost ~]# for i; do echo $i ; done      去掉in变量列表,相当于in"$@"
  
    howold
  
    are
  
    you.
  
    [root@localhost ~]# for i in "$@" ; doecho $i ; done  在有双引号的情况下,参数里引号内容当作一个参数输出,这才真正符合我们传入的参数需求。
  
    howold
  
    are
  
    you.
  
    .
  获取系统运行级别:
    # runlevel=$(set -- $(runlevel);eval "echo \$$#" )  
    # echo $runlevel
  
    3
  1. eval command-line
  其中command-line是在终端上键入的一条普通命令行。然而当在它前面放上eval时,其结果是shell在执行命令行之前扫描它两次。如:
  pipe="|"
  evalls $pipe wc -l
  shell第1次扫描命令行时,它替换出pipe的值|,接着eval使它再次扫描命令行,这时shell把|作为管道符号了。
  如果变量中包含任何需要shell直接在命令行中看到的字符(不是替换的结果),就可以使用eval。命令行结束符(;| &),I/o重定向符(< >)和引号就属于对shell具有特殊意义的符号,必须直接出现在命令行中。
  2. eval echo \$$# 取得最后一个参数
  如:cat last
  evalecho \$$#
  ./lastone two three four
  four
  第一遍扫描后,shell把反斜杠去掉了。当shell再次扫描该行时,它替换了$4的值,并执行echo命令
  3.以下示意如何用eval命令创建指向变量的“指针”:
  x=100
  ptrx=x
  eval echo \$$ptrx 指向ptrx,用这里的方法可以理解b中的例子
  100 打印100
  eval $ptrx=50 将50存到ptrx指向的变量中。
  echo$x
  50 打印50



运维网声明 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.iyunv.com/thread-554539-1-1.html 上篇帖子: shell脚本中报错dirname:无效选项 -- b 下篇帖子: shell输出彩色的字符串
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

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

扫描微信二维码查看详情

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


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


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


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



合作伙伴: 青云cloud

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