文章目录

  • 变量的替换
    • 使用trap设计一个用于反应程序执行过程的脚本
  • 变量的赋值
  • `bash`变量是不区分类型的
  • 特殊变量类型

变量是什么,变量是脚本编程中进行数据表现的一种方法,说白了,变量不过是计算机为了保留数据项,而在内存中分配的一个位置或一组位置的标识或名字。

变量的替换

变量的名字就是保存变量值的地方,引用变量的值就叫做变量替换

$

shell中要仔细区分变量的名字和变量的值,如果a是一个变量,那么$a就是引用这个变量的值,即变量所包含的数据。

andrew@andrew-Thurley:/work/linux-sys/bash$a=1
andrew@andrew-Thurley:/work/linux-sys/bash$ echo a
a
andrew@andrew-Thurley:/work/linux-sys/bash$ echo $a
1

当变量裸体出现的时候,也就是说没有$前缀的时候,那么变量可能存在如下几种情况

  1. 变量被声明或被赋值
  2. 变量被unset
  3. 变量被exporte
  4. 或者处在一种特殊的情况下,变量代表一种信号

trap.sh

#!/bin/bash
# 使用trap来捕捉变量值.trap 'echo Variable Listing --- a = $a b = $b' EXIT
# EXIT是脚本中exit命令所产生信号的名字.
#
# "trap"所指定的命令并不会马上执行,
#+ 只有接收到合适的信号, 这些命令才会执行.
echo "This prints before the \"trap\" --"
echo "even though the script sees the \"trap\" first."
echo
a=39
b=36
exit 0
andrew@andrew-Thurley:/work/linux-sys/bash/2.基本/src$ bash trap.sh
This prints before the "trap" --
even though the script sees the "trap" first.Variable Listing --- a = 39 b = 36

被一双引号""括起来的变量替换是不会被阻止的,所以双引号被称为部分引用,有的时候又被称为弱引用。如果是使用单引号的话''那么比变量的替换就会被禁止,变量名只会被解释成字面的意思,不会出发变量的替换。所以单引号被称为全引用,有的时候被称为强引用

#!/bin/bash# 变量赋值和替换a=375
hello=$a#------------------------------------------------------------------
# 强烈注意, 在赋值的的时候, 等号前后一定不要有空格.
# 如果出现空格会怎么样?# "VARIABLE =value"
#
#% 脚本将尝试运行一个"VARIABLE"的命令, 带着一个"=value"参数.# "VARIABLE= value"
#
#% 脚本将尝试运行一个"value"的命令,
#+ 并且带着一个被赋值成""的环境变量"VARIABLE".
#------------------------------------------------------------------
echo hello
# 没有变量引用, 只是个hello字符串.
echo $hello
echo ${hello} # 同上.echo "$hello"
echo "${hello}"echohello="A B C D"
echo $hello
# A B C D
echo "$hello" # A B C D
# 就象你看到的echo $hello和echo "$hello"将给出不同的结果.
# ===============================================================
# 引用一个变量将保留其中的空白, 当然, 如果是变量替换就不会保留了.
# ===============================================================echoecho '$hello' # $hello
#
# 全引用的作用将会导致"$"被解释为单独的字符,
#+ 而不是变量前缀.# 注意这两种引用所产生的不同的效果.# 设置为空值.
hello=    echo "\$hello (null value) = $hello"
# 注意设置一个变量为null, 与unset这个变量, 并不是一回事
#+ 虽然最终的结果相同(具体见下边).# --------------------------------------------------------------# 可以在同一行上设置多个变量,
#+ 但是必须以空白进行分隔.
# 慎用, 这么做会降低可读性, 并且不可移植.var1=21 var2=22 var3=$V3
echo
echo "var1=$var1
var2=$var2
var3=$var3"# 在老版本的"sh"上可能会引起问题.# --------------------------------------------------------------echo; echonumbers="one two three"
#
other_numbers="1 2 3"
## 如果在变量中存在空白, If there is whitespace embedded within a variable,
#+ 那么就必须加上引用.
# other_numbers=1 2 3
# 给出一个错误消息.
echo "numbers = $numbers"
echo "other_numbers = $other_numbers"
# other_numbers = 1 2 3
# 不过也可以采用将空白转义的方法.
mixed_bag=2\ ---\ Whatever
#在转义符后边的空格(\).echo "$mixed_bag"
# 2 --- Whateverecho; echoecho "uninitialized_variable = $uninitialized_variable"
# Uninitialized变量为null(就是没有值).
uninitialized_variable=
# 声明, 但是没有初始化这个变量,#+ 其实和前边设置为空值的作用是一样的.
echo "uninitialized_variable = $uninitialized_variable"# 还是一个空值.uninitialized_variable=23
# 赋值.
unset uninitialized_variable
# Unset这个变量.
echo "uninitialized_variable = $uninitialized_variable"# 还是一个空值.
echoexit 0

像C语言中的变量一样,一个未初始化的变量将会是null值 - 就是未赋值(但并不代表值是0),在给变量 赋值之前就使用这个变量通常会引起问题。

### 小知识加油站–trap

trap的格式如下,功能就是捕捉信号,并对信号进行处理

trap [-lp] [[arg] sigspec ...]

trap使用官方简介

  trapAutomatically execute commands after receiving signals by processes or the operating system.Can be used to perform cleanups for interruptions by the user or other actions.- List available signals to set traps for:trap -l- List active traps for the current shell:trap -p- Set a trap to execute commands when one or more signals are detected:trap 'echo "Caught signal SIGHUP"' SIGHUP- Remove active traps:trap - SIGHUP SIGINT
  • arg可以是shell命令或者自定义函数
  • sigspec可以是以下的一个或多个
  • 定义在<signal.h>中的信号名或者数值。信号名的大小写不敏感,SIG这个前缀也是可选的。以下的命令的效果都是一样的
trap "echo SIGINT" SIGINT
trap "echo SIGINT" sigint
trap "echo SIGINT" 2
trap "echo SIGINT" int
trap "echo SIGINT" Int

调试脚本时,trap经常用到的信号量

  • EXIT:在shell退出前执行trap设置的命令,也可以指定为0
  • RETURN:在.和``source执行其他脚本返回时,执行trap`设置的命令
  • DEBUG:在任何命令执行前执行trap设置的命令,但对于函数仅在函数的第一条命令前执行一次
  • ERR:在命令结果为非0时,执行trap设置的命令
#! /bin/bash
# 使用trap实现在每个函数开始之前打印以便打印,这样就能准确的定位到函数的位置
# 从而实现对脚本的调试
trap "echo before a func is called" DEBUG
# 当. 或者 source 调用结束的时候出发
trap "echo . or source is called "  RETURN
func()
{echo "不管你信不信,这是一个函数"exit 0
}
# 测试
echo "call ."
. traptest# 函数的调用
func
# DEBUG 查看调试信号是否有效的设置了
# trap -p RETURN
# trap -p DEBUGexit 0

执行结果

andrew@andrew-Thurley:/work/linux-sys/bash/2.基本/src$ bash trap_func.sh
before a func iis called
before a func iis called
call .
before a func iis called
. or source is called
before a func iis called
不管你信不信,这是一个函数
  • trap -l:列出所有信号的数值和名字,类似于kill -l
andrew@andrew-Thurley:~$ trap -l1) SIGHUP  2) SIGINT    3) SIGQUIT   4) SIGILL    5) SIGTRAP6) SIGABRT  7) SIGBUS    8) SIGFPE    9) SIGKILL  10) SIGUSR1
11) SIGSEGV  12) SIGUSR2  13) SIGPIPE  14) SIGALRM  15) SIGTERM
16) SIGSTKFLT    17) SIGCHLD  18) SIGCONT  19) SIGSTOP  20) SIGTSTP
21) SIGTTIN  22) SIGTTOU  23) SIGURG   24) SIGXCPU  25) SIGXFSZ
26) SIGVTALRM    27) SIGPROF  28) SIGWINCH 29) SIGIO    30) SIGPWR
31) SIGSYS   34) SIGRTMIN 35) SIGRTMIN+1   36) SIGRTMIN+2   37) SIGRTMIN+3
38) SIGRTMIN+4   39) SIGRTMIN+5   40) SIGRTMIN+6   41) SIGRTMIN+7   42) SIGRTMIN+8
43) SIGRTMIN+9   44) SIGRTMIN+10  45) SIGRTMIN+11  46) SIGRTMIN+12  47) SIGRTMIN+13
48) SIGRTMIN+14  49) SIGRTMIN+15  50) SIGRTMAX-14  51) SIGRTMAX-13  52) SIGRTMAX-12
53) SIGRTMAX-11  54) SIGRTMAX-10  55) SIGRTMAX-9   56) SIGRTMAX-8   57) SIGRTMAX-7
58) SIGRTMAX-6   59) SIGRTMAX-5   60) SIGRTMAX-4   61) SIGRTMAX-3   62) SIGRTMAX-2
63) SIGRTMAX-1   64) SIGRTMAX
  • trap -p:列出通过trap设置过的信号处理命令
andrew@andrew-Thurley:~$ trap -p
trap -- 'name ' SIGINT
trap -- '' SIGTSTP
trap -- '' SIGTTIN
trap -- '' SIGTTOU
trap -- 'name ' RETURN
trap "" sigspec :忽略sigspec指定的信号
trap "do something" sigspec:收到sigspec指定的信号时,do some thing后,继续执行后续命令。
trap sigspec or trap - sigspec:恢复sigspec指定的信号的默认行为

注意

  • 在函数中设置的trap也是全局生效的
#!/bin/bash
# trap设置在函数中的tap也是全局有效的
foo()
{    trap "echo func is called" DEBUG
}# 输出 func is called
foo
# 调试触发
#trap -p DEBUG
# 输出trap -- 'echo func is called' SIGINT
exit 0
  • 对于同一个信号,只有最后一次trap生效
  • trap只在本进程内有效,它的子进程不会继承trap的设置。

使用trap设计一个用于反应程序执行过程的脚本

#!/bin/bash
# 使用trap来捕捉变量值.# EXIT代表在函数退出前,执行trap
trap 'echo Variable Listing --- ret=${ret}' EXITps -A
if [ $? == 0 ];thenecho "commond exec OK!"ret=0
elseret=1
fiecho "注意这里,还没有调用trap"# trap是在退出的时候清理程序时调用的
exit 0

变量的赋值

=

赋值操作(前后都不能有空白)

注意:因为=-eq都可以用作条件测试操作,所以不要与这里的赋值操作相混淆。

=既可以用作条件测试操作,也可以用于赋值操作,这需要视具体上下文而定

简单的变量赋值

#!/bin/bash
# "裸体"变量
echo
# 变量什么时候是"裸体"的, 比如前边少了$的时候?
# 当它被赋值的时候, 而不是被引用的时候.
# 赋值
a=879
echo "The value of \"a\" is $a."
# 使用'let'赋值
let a=16+5
echo "The value of \"a\" is now $a."
echo
# 在'for'循环中(事实上, 这是一种伪赋值):
echo -n "Values of \"a\" in the loop are: "
for a in 7 8 9 11
doecho -n "$a "
done
echo
echo
# 使用'read'命令进行赋值(这也是一种赋值的类型):
echo -n "Enter \"a\" "
read a
echo "The value of \"a\" is now $a."
echoexit 0

简单又不简单的的两种类型的变量赋值

#!/bin/bash
a=23
# 简单的赋值
echo $a
b=$a
echo $b
# 现在让我们来点小变化(命令替换).
a=`echo Hello!`
# 把'echo'命令的结果传给变量'a'
echo $a
# 注意, 如果在一个#+的命令替换结构中包含一个(!)的话,
#+ 那么在命令行下将无法工作.
#+ 因为这触发了Bash的"历史机制."
# 但是, 在脚本中使用的话, 历史功能是被禁用的, 所以就能够正常的运行.
a=`ls -l`
echo $a
echo
echo "$a"
exit 0

使用$(...)机制来进行变量赋值(这是一种比后置引用(反引号`)更新的一种方法). 事实上这两种
方法都是命令替换的一种形式.

# From /etc/rc.d/rc.local
R=$(cat /etc/redhat-release)
arch=$(uname -m)

bash变量是不区分类型的

不像其他程序语言一样,bash并不区分变量的类型,本质上bash变量都是字符串。实际的作用依赖于上下文,Bash也允许比较操作和整数操作,其中的关键因素就是,变量中的值是否只有数值。

#!/bin/bash
# int-or-string.sh: 整型还是字符串?a=2334 #整型.
let "a += 1"
echo "a = $a " # a = 2335
echo  # 还是整型.
b=${a/23/BB}
# 将"23"替换成"BB".
# 这将把变量b从整型变为字符串.
echo "b = $b"
# b = BB35
declare -i b
# 即使使用declare命令也不会对此有任何帮助.
echo "b = $b"
# b = BB35
let "b += 1"
# BB35 + 1 =
echo "b = $b"
# b = 1
echo
c=BB34
echo "c = $c"
# c = BB34
d=${c/BB/23}
# 将"BB"替换成"23".
# 这使得变量$d变为一个整形.
echo "d = $d"
# d = 2334
let "d += 1"
# 2334 + 1 =
echo "d = $d"
# d = 2335
echo# null变量会如何呢?
e=""
echo "e = $e"
# e =
let "e += 1"
# 算术操作允许一个null变量?
echo "e = $e"
# e = 1
echo
# null变量将被转换成一个整型变量.# 如果没有声明变量会怎样?
echo "f = $f"
# f =
let "f += 1"
# 算术操作能通过么?
echo "f = $f"
# f = 1
echo
# 未声明的变量将转换成一个整型变量.
# 所以说Bash中的变量都是不区分类型的.
exit 0

不区分变量的类型既是幸运的事情也是悲惨的事情. 它允许你在编写脚本的时候更加的灵活(但是也足
够把你搞晕!), 并且可以让你能够更容易的编写代码. 然而, 这也很容易产生错误, 并且让你养成糟糕
的编程习惯.

这样的话, 程序员就承担了区分脚本中变量类型的责任. Bash是不会为你区分变量类型的

特殊变量类型

局部变量

这种变量只有代码块或者函数中才可见

如果变量用local 来声明, 那么它就只能够在该变量被声明的代码块中可见. 这个代码块就是局
部"范围". 在一个函数中, 一个局部变量只有在函数代码块中才有意义.

环境变量

这种变量将影响用户接口和shell的行为

bash-高级编程--变量和参数介绍相关推荐

  1. bash--shell高级编程-变量的替换

    变量的名字就是变量保存值的地方,引用变量的值就叫做变量替换. 让我们仔细的区别变量的名字和变量的值. 如果 variable1 是一个变量的名字, 那么 $variable1 就 是引用这变量的值, ...

  2. 网络编程 socket函数参数介绍

    SOCKET参数: 1.地址的类型 a.AF_INET 2  internet协议版本4(ipv4)地址系列. b.AF_INET6 23  Internet协议版本6(ipv6)地址系列. c.AF ...

  3. bash-shell高级编程--求最大公约数

    一个完整的编程语言肯定少不了对计算能力的支持,同样shell脚本中也提供了对计算能力的支持,下面的脚本就是实现求两个数的最大公约数的shell脚本. 已在ubuntu16.04上验证过 #!/bin/ ...

  4. 来吧,嘤!,c++高级编程介绍

    c++高级编程介绍 学c++确实是件痛苦的事,这水平得一步步抬上去,实话说学校教的也不好,就更痛苦了,还要学这学那,对技术没半点提升.最近就在学这个,没得方向,只好自己归纳了.嘤!嘤! 目录 预处理 ...

  5. 遨博协作机器人高级编程 -AUBOPE SDK Python接口介绍与使用

    目录 一.简介 二.环境版本 三.Python SDK接口简介 1.Python SDK接口数据 2. Python SDK接口函数示例 四.任务实施 五.任务拓展 一.简介 大家好,本篇文章主要针对 ...

  6. OC高级编程——深入block,如何捕获变量,如何存储在堆上

    OC高级编程--深入block,如何捕获变量,如何存储在堆上 首先先看几道block相关的题目 这是一篇比较长的  博文 ,前部分是block的测试题目,中间是block的语法.特性,block讲解b ...

  7. 【嵌入式】C语言高级编程-可变参数宏(12)

    00. 目录 文章目录 00. 目录 01. 可变参数宏概述 02. ##符号 03. 可变参宏另外一种写法 04. 内核中的可变参数宏 05. 附录 01. 可变参数宏概述 #include < ...

  8. linux脚本算术函数,Linux基础之bash脚本编程初级-变量与算术运算

    什么是变量? 变量最初来源于数学,指的是非固定的值可变化的数通常用拉丁字母表示.在计算机中变量它依旧指的是可变化的数,只不过表现形式有些变化.它指的是变量名+所指向的内存空间. 以下实验环境均在Cen ...

  9. Linux基础之bash脚本编程初级-变量与算术运算

    什么是变量? 变量最初来源于数学,指的是非固定的值可变化的数通常用拉丁字母表示.在计算机中变量它依旧指的是可变化的数,只不过表现形式有些变化.它指的是变量名+所指向的内存空间. 以下实验环境均在Cen ...

最新文章

  1. 【书评:Oracle查询优化改写】第14章 结尾章
  2. SAP MM ME21N 创建PO时报错 - Net price in CNY becomes too large – 之原因分析
  3. 【全栈React】第6天: 状态
  4. 如何正确访问 redis 中的海量数据?避免事故产生
  5. 2010年第一届蓝桥杯省赛 —— 第二题
  6. AGV (Automated guided vehicle)基础(二) - AGV的视觉算法 - RGB - D 算法
  7. Netty工作笔记0069---Protobuf使用案例
  8. c盘不能新建文件的解决办法
  9. 在CentOS 7中安装Jetty服务器
  10. Centos中安装memcached
  11. 提醒:使用过期Win10预览版后果很严重
  12. matlab批量修改文件名
  13. 联通鸿蒙卡怎么样,联通不限流量卡,联通无限流量,正规资费
  14. 狄利克雷分布公式_一文详解隐含狄利克雷分布(LDA)
  15. RJ45接头接口定义
  16. MacBook Pro出现kernel_task占用CPU非常高问题
  17. Android 使用Navigation 跳转页面时发生crash
  18. 一张新型肺炎地区分布地图是怎么制作的?
  19. MXNet:基础和入门
  20. 【Unity】Unity中影响性能的几个因素

热门文章

  1. 最长公共子序列问题 (LCS)
  2. poj 2455 Secret Milking Machine(二分枚举+最大流)
  3. hdu 3065 病毒侵袭持续中(AC自动机)
  4. JPA(二):HellWord工程
  5. databinding在android studio2.3版本后不再默认支持使用
  6. bzoj1025题解
  7. Linux文件系统简介及常用命令
  8. 坚持使用GNU/Linux
  9. 解决msgfmt无法使用的问题
  10. apt-get 与 yum的区别 (转)