1.特殊变量
实际工作中我们不可避免的遇到一些xxxx.sh脚本文件,实际阅读shell脚本代码时经常会遇到很多特殊变量(例如:$0、$n、$#、$@、$*、$?、$$等),我们常常会被这些特殊符号折腾的脑壳痛,本期文章就会对这些奇奇怪怪的特殊符号进行一个总结,以便后续工作中遇到时可以及时复习。废话不多说,直接开干!查阅了网上的一些资料,对这些特殊变量的整理如下所示:
序号 | 特殊变量 | 含义 |
1 |
$0 | 当前脚本的文件名称 |
2 | $n | 传递给脚本或函数的参数,n是一个数字,表示第几个参数。例如:第1个参数是$1,第2个参数是$2,其余依次类推...... |
3 | $# | 传递给脚本或函数的参数个数 |
4 | $* | 传递给脚本或函数的所有参数 |
5 | $@ | 传递给脚本或函数的所有参数,与$*的区别稍后会进行比较 |
6 |
$? | 返回执行完上一条命令后,退出时的状态或函数的返回值 |
7 |
$$ | 当前shell进程的ID |
下面用一些简单的测试代码向大家展示一下,在shell脚本中上述特殊变量的应用。
1.1 $$的用法
可以看到我们将特殊变量$$的值打印出来了,即当前shell进程的ID号为6929。
[cdl@h3c/home/cdl]$echo "hello world" $$ hello world 6929
1.2 $0、$n、$#、$*、$@的用法
可以编写一个简单的测试脚本demo.sh,运行脚本时给此脚本传递一些参数(简称:命令行参数),如下所示。命令行参数用$n表示,例如:$1表示第一个参数、$2表示第二个参数、$3表示第三个参数,其余依次类推......
[cdl@h3c/home/cdl/Test]$cat demo.sh #!/bin/bash :<<comment echo "这是shell脚本中整段代码注释的方法,不需要逐行用#进行注释" comment echo "当前文件名称: $0" echo "命令行参数中的第1个参数: $1" echo "命令行参数中的第2个参数: $2" echo "传递给脚本或函数的所有参数: $@" echo "传递给脚本或函数的所有参数: $*" echo "传递给脚本或函数的所有参数总数: $#" [cdl@h3c/home/cdl/Test]$ [cdl@h3c/home/cdl/Test]$chmod 777 demo.sh [cdl@h3c/home/cdl/Test]$ [cdl@h3c/home/cdl/Test]$ [cdl@h3c/home/cdl/Test]$./demo.sh Curry Durant 当前文件名称: ./demo.sh 命令行参数中的第1个参数: Curry 命令行参数中的第2个参数: Durant 传递给脚本或函数的所有参数: Curry Durant 传递给脚本或函数的所有参数: Curry Durant 传递给脚本或函数的所有参数总数: 2
1.3 $?的用法
$?可以获取上一条命令的退出状态,退出状态是一个数字。如果退出状态为非0值,则表示上一条命令执行异常啦。我们可以故意将demo.sh脚本中的最后一行命令修改错误,打印一下$?为127。由此,我们可以知道demo.sh脚本的最后一行命令执行失败啦。
[cdl@h3c/home/cdl/Test]$cat demo.sh #!/bin/bash :<<comment echo "这是shell脚本中整段代码注释的方法,不需要逐行用#进行注释" comment echo "当前文件名称: $0" echo "命令行参数中的第1个参数: $1" echo "命令行参数中的第2个参数: $2" echo "传递给脚本或函数的所有参数: $@" echo "传递给脚本或函数的所有参数: $*" eho "传递给脚本或函数的所有参数总数: $#" [cdl@h3c/home/cdl/Test]$./demo.sh Curry Durant 当前文件名称: ./demo.sh 命令行参数中的第1个参数: Curry 命令行参数中的第2个参数: Durant 传递给脚本或函数的所有参数: Curry Durant 传递给脚本或函数的所有参数: Curry Durant ./demo.sh: line 15: eho: command not found [cdl@h3c/home/cdl/Test]$echo $? 127
1.4 $@与$*的区别
$*和$@都可以表示传递给脚本或者函数的所有参数,$*和$@不被双引号""包含时,两者都是以$1、$2、$3...$n的形式逐一输出所有参数;但是当$*和$@被双引号""包含时,两者就会有区别:$*会将所有参数作为一个整体输出(具体形如"$1 $2 $3 ... $n"的格式输出所有参数);而$@会将各个参数分开输出(具体形如$1、$2、$3...$n的格式输出所有参数)。
如果直接用echo直接输出$*和$@是看不出来两者的区别,例如上面的demo.sh脚本;但如果使用for循环依次输出所有参数时,立即就可以看出两者的区别。如下所示:
[cdl@h3c/home/cdl/Test]$cat test.sh #!/bin/bash echo "\$* =" $* echo "\"\$*\" =" $* echo "print each param from \$*" for var in $* do echo "$var" done echo "print each param from \"\$*\"" for var in "$*" do echo "$var" done echo "====================此处是分割线========================" echo "\$@ =" $@ echo "\"\$@\" =" $@ echo "print each param from \$@" for var in $@ do echo "$var" done echo "print each param from \"\$@\"" for var in "$@" do echo "$var" done [cdl@h3c/home/cdl/Test]$chmod 777 test.sh [cdl@h3c/home/cdl/Test]$./test.sh A B C D $* = A B C D "$*" = A B C D print each param from $* A B C D print each param from "$*" A B C D ====================此处是分割线======================== $@ = A B C D "$@" = A B C D print each param from $@ A B C D print each param from "$@" A B C D
2.if条件测试
总结完shell脚本中的特殊变量,接着再输出一下也是shell脚本中很常见的if条件测试。之所以对这一部分进行总结,原因是自己遇到的编译脚本中遇到实在是太多了。此外,前几天也有别人在问我这个问题,一时竟记不起来。于是,本期文章的第二部分会对如何测试文件表达式、字符串表达式、整数表达式进行梳理总结。
2.1 测试文件表达式
文件表达式中涉及很多测试选项,在实际脚本文件中应用的也很多。同时,查找网上资料将常用的一些测试选项整理如下。最后,用一个简单的脚本样例进行说明。
测试文件表达式
[cdl@h3c/home/cdl/Test]$cat hello.sh #!/bin/bash FILE=~/.bashrc if [ -e "$FILE" ]; then if [ -f "$FILE" ]; then echo "$FILE是一个普通文件" fi if [ -d "$FILE" ]; then echo "$FILE是一个目录" fi if [ -r "$FILE" ]; then echo "$FILE是一个可读文件" fi if [ -w "$FILE" ]; then echo "$FILE是一个可写文件" fi if [ -x "$FILE" ]; then echo "$FILE 是一个可执行文件" fi else echo "$FILE是一个不存在的文件" exit 1 fi exit [cdl@h3c/home/cdl/Test]$chmod 777 hello.sh [cdl@h3c/home/cdl/Test]$./hello.sh /home/cdl/.bashrc是一个普通文件 /home/cdl/.bashrc是一个可读文件 /home/cdl/.bashrc是一个可写文件 /home/cdl/.bashrc 是一个可执行文件
2.2 测试字符串表达式
有了前面测试文件表达式的经验,使用同样的方法对字符串表达式进行测试。同时,查找网上资料将常用的一些测试选项整理如下。最后,用一个简单的脚本样例进行说明。
测试字符串表达式
[cdl@h3c/home/cdl/Test]$cat debug.sh #!/bin/bash ANSWER=maybe if [ -z "$ANSWER" ]; then # >&2:将There is answer错误信息重定向到标准错误(2是标准错误对应的文件描述符) echo "There is no answer." >&2 exit 1 elif [ "$ANSWER" = "no" ]; then echo "The answer is no" elif [ "$ANSWER" = "yes" ]; then echo "The answer is yes" elif [ "$ANSWER" = "maybe" ]; then echo "The answer is maybe" else echo "The answer is unknown" fi [cdl@h3c/home/cdl/Test]$chmod 777 debug.sh [cdl@h3c/home/cdl/Test]$./debug.sh The answer is maybe
2.3 测试整数表达式
使用同样的方法对整数表达式进行测试,测试时注意大于、小于、等于选项的英文表示。同时,查找网上资料将常用的一些测试选项整理如下。最后,用一个简单的脚本样例进行说明。
测试整数表达式
[cdl@h3c/home/cdl/Test]$cat int.sh #!/bin/bash INT=-5 if [ -z "$INT" ]; then echo "INT is empty" >&2 exit 1 fi if [ $INT -eq 0 ]; then echo "INT is zero" else if [ $INT -lt 0 ]; then echo "INT is negative" else echo "INT is positive" fi if [ $((INT % 2)) -eq 0 ]; then echo "INT is even" else echo "INT is odd" fi fi [cdl@h3c/home/cdl/Test]$chmod 777 int.sh [cdl@h3c/home/cdl/Test]$./int.sh INT is negative INT is odd