linux shell 脚本的编写是Linux程序员最基本也是必须学会的技能。
这里主要介绍学习shell脚本的基本基础。
命令解释器
#指定命令解释器
#! /bin/bash
...
命令解释器:shell脚本中第1行的 #! /bin/bash 告诉当前shell应该调用哪个shell来执行当前的程序。
shell脚本中的注释风格
- 单行注释:在前面加一个"#"
#注释1
#注释2
#注释3
- 多行注释:使用冒号":"配合here document 使用
:<<BLOCK
....注释内容
BLOCK
变量和引用
变量的命名
在shell 中,变量名可以由字母、数字或者下划线组成,并且只能以字母或者下划线开头。
变量的类型
根据变量类型确定的时间,可以将程序设计语言分为两类,分别是静态类型语言和动态类型语言。
静态类型语言:在程序的编译期间就确定变量类型的语言,例如JAVA、C++ 和PASCAL
动态类型语言:在程序执行过程中才确定变量的数据类型的语言,如VBScript、PHP、Python。
shell是一种动态类型语言和弱类型语言。
在shell中,变量的数据类型无需显示地声明,变量地数据类型会根据不同的操作有所变化。
准确地讲,shell中的变量是不分数据类型的,统一地按照字符串存储。
例子1:变量的数据类型
#!/bin/bash
#定义变量下x,并且赋值为123
x=123
#变量x加1
let "x += 1"
#输出变量x的值
echo "x = $x"
#替换x中的1为abc,并且将值赋给变量y
y=${x/1/abc}
#输出变量y的值
echo "y = $y"
#声明变量y(整型变量)
declare -i y
#输出变量y的值
echo "y = $y"
#变量y的值加1
let "y += 1"
#输出变量y的值
echo "y = $y"
输出为:
x = 124
y = abc24
y = abc24
y = 1
为了执行加法运算,shell会自动进行数据类型的转换,如果遇到含有非数字的字符串,则该字符串将被转换成整数0。
shell变量的定义
在shell中,通常情况下用户可以直接使用变量,无需先进行定义。
当用户第一次使用某个变量名时,实际上就同时定义了这个变量,在变量的作用域内,用户都可以使用该变量。
例2: 直接使用变量定义变量
#! /bin/bash
#定义变量a
a=1
#定义变量b
b="hello"
# 定义变量c
c="hello world"
通过以上方式可以非常方便地定义变量,但是,对于变量的某些属性却不容易控制,例如,变量的类型和读写属性等。为了更好地控制变量地相关属性,bash提供了一个名称为 declare 的命令来声明变量,该命令的基本语法如下:
declare attribute variable
其中,attributeattributeattribute表示变量的属性,常用属性如下:
- -p:显示所有变量的值
- -i:将变量定义为整数。在之后就可以直接对表达式求值,结果只能是整数。如果求值失败或者不是整数,就设置为0
- -r:将变量声明为只读变量。但这没有必要。所有变量都不必显示定义就可以用做数组
- -f:显示所有自定义函数,包括名称和函数体
- -x:将变量设置成环境变量,这样在随后的脚本和程序中可以使用
参数variable表示变量名称。
例3:使用不同的方法声明变量
#! /bin/bash
#定义变量x,并将一个算术式赋给它
x=6/3
echo "$x"
#定义变量x为整数
declare -i x
echo "$x"
#将算术式赋给变量x
x=6/3
echo "$x"
#将字符串赋给变量x
x=hello
echo "$x"
#将浮点数赋给变量x
x=3.14
echo "$x"
#取消变量x的整数属性
declare +i x
#重新将算术式赋给变量x
x=6/3
echo "$x"
#求表达式的值
x=$[6/3]
echo "$x"
#求表达式的值
x=$((6/3))
echo "$x"
#声明只读变量x
declare -r x
echo "$x"
#尝试为只读变量赋值
x=5
echo "$x"
结果为:
6/3
6/3
2
0
declare_data.sh: line 16: 3.14: syntax error: invalid arithmetic operator (error token is ".14")
0
6/3
2
2
2
declare_data.sh: line 35: x: readonly variable
因为bash并不内置对浮点数的支持,所以得到了上图结果中的第一个错误;第二个错误是因为加了只读权限,尝试修改便会报错。
引号
在shell编程中,正确理解引号的作用非常重要。
shell语言中一共有三种引号,分别为单引号(’’)、双引号("")和反引号(``)。这3种引号的作用是不同的:
- 单引号括起来的字符都作为普通字符出现;
- 由双引号括起来的字符,除“$”、“\”、“’”和“"”这几个字符仍是特殊字符并保留其特殊功能外,其余字符仍作为普通字符对待;
- 由反引号括起来的字串被shell解释为命令,在执行时,shell首先执行该命令,并以它的标准输出结果取代整个反引号部分。
变量的作用域
全局变量
在shell语言中,全局变量是使用范围较大的变量,它不仅限于某个局部使用。全局变量可以在脚本中定义,也可以在某个函数中定义。
在脚本中定义的变量都是全局变量,其作用域为从被定义的地方开始,一直到shell脚本结束或者被显示的删除。
所以在函数内部定义的默认情况下也是全局变量,其作用域为从函数被调用时执行变量的定义的地方开始,一直到shell脚本结束或者被显示地删除为止
例4: 全局变量
#! /bin/bash
#定义函数
func()
{
echo "$v1"
#修改变量的值
v1=200
}
#在脚本中定义全局变量x
v1=100
#调用函数
func
echo "$v1"
局部变量
在shell中,通过关键字 local 定义局部变量,同时,上述提到的函数参数也是局部变量。
例5:使用local关键字定义局部变量
#! /bin/bash
func()
{
#使用local关键字定义局部变量
local v2=200
}
#调用函数
func
echo "$v2"
结果为空:
由于使用了local来定义v2变量,所以在函数外部就访问不到v2的值,因此得到一个空值。
如果用户在函数外面定义了一个全局变量,同时在某个函数内部定义又存在相同名称的局部变量,而在调用该函数时,函数内部的局部变量会屏蔽函数外部定义的全局变量。也就是说,在出现同名的情况下,函数内部的局部变量会优先被使用。
系统变量
shell语言的系统变量主要在对参数判断和命令返回值判断时使用,包括脚本和函数的参数,以及脚本和函数的返回值。
shell语言中的系统变量并不多,但是十分有用,特别是在做一些参数检测的时候。
变量名 | 含义 |
---|---|
$n | 表示传递给脚本的第n个参数, $1表示第1个参数,$2表示第二个参数… |
$# | 脚本的参数个数 |
$@ | 以”参数1“ ”参数2“ ”参数3“…的形式返回参数的值 |
$* | 以”参数1 参数2 参数3…“的形式返回所有参数的值 |
$0 | 此脚本的名字 |
$? | 上一条命令的返回值 |
$$ | 返回本进程的进程ID |
例6:使用系统变量
#! /bin/bash
#输出脚本参数的个数
echo "the number of parameters is $#"
#输出上一个命令的状态码
echo "the return code of last command is $?"
#输出脚本名称
echo "the script name is $0"
#输出所有的参数
echo "the parameters are $*"
#输出其中的几个参数
#注意:此处不能写成$11,不然会被误认为是$1变量加上一
echo "\$1=$1; \$2=$2; \$11=${11}"
结果:
rootVM_16_3_centos base]$ ./param.sh a b c d e f g h i j k l m n
the number of parameters is 14
the return code of last command is 0
the script name is ./param.sh
the parameters are a b c d e f g h i j k l m n
$1=a; $2=b; $11=k
变量的赋值和清空
一个没有初始化的shellshellshell变量被认为是一个空字符串。用户可以通过变量的赋值操作来完成变量的声明并赋予一个特定的值。并且可以通过赋值语句为一个变量多次赋值,以改变其值。
在shell中,变量的赋值可以用如下语法:
variable_name=value
其中,variable_ name表示变量名,value表示将要赋给变量的值。
一般情况下,shell中将所有普通变量的值都看做字符串。如果value中包含空格、制表符和换行符,则必须用单引号或者双引号将其引起来。双引号中允许变量替换,而单引号中则不允许
中间的"="称为赋值符号,赋值符号的左右两边不能直接跟空格,否则shell会将其视为命令
通过在变量名前加上“$”来获取变量的值。
例7:引用shell变量
#! /bin/bash
v1=10
v2='RedHat Linux'
v3="RedHat Linux $HOSTTYPE"
v4=12345
#输出变量v1的值
echo "$v1"
#输出变量v2的值
echo "$v2"
#输出变量v3的值
echo "$v3"
#输出变量v4的值
echo "$v4"
# 字符串是可以直接连接在一起的
## 错误的写法
echo "$v4abc"
## 正确的写法
echo "${v4}abcd"
结果
10
RedHat Linux
RedHat Linux x86_64
12345
12345abcd
清除变量
不需要某个变量时,可以将其清除。当变量被清除后,其所代表的值也会消失。清除变量使用 unset 语句,其语法如下:
#! /bin/bash
v1="Hello world"
echo "$v1"
unset v1 #清除变量v1
echo "the value of v1 has been reset"
echo "clear$v1"
结果
Hello world
the value of v1 has been reset
clear
命令替换
所谓命令替换,是指在 shell 程序中,将某个 shell 的命令的执行结果赋给某个变量。在 bash 中,有两种语法可以进行命令替换,分别使用反引号和圆括号,如下
`shell_command`
$(shell_command)
网友评论