在程序设计语言中,变量是一个非常重要的概念。也是初学者在进行 Shell 程序设计之前必须掌握的 一个非常基础的概念。只有理解变量的使用方法,才能设计出良好的程序。本节将介绍Shell 中变量的相关知识。
1、什么是变量
顾名思义,变量就是程序设计语言中的一个可以变化的量,当然,可以变化的是变量的值。几乎所有的程序设计语言中都有定义变量,并且其涵义也大同小异。从本质上讲,变量就是在程序中保存用户数据的一块内存空间,而变量名就是这块内存空间的地址。
在程序的执行过程中,保存数据的内存空间的内容可能会不断地发生变化,但是,代表内存地址的变量名却保持不变。
2、变量的命名
- 可以使用数字,字母,和下划线给变量命名
- 不能用数字开头
- 如果给同一个变量赋值多次,最后一次赋值会覆盖之前的值
合法的变量名:name NMAE name1 name_1 Name_1
不合法的变量名:1name name*1 name_1%
3、查看变量的值
①、查看单个变量的值
- echo $PATH
- echo ${PATH}
- printf "$PATH\n"
- printf "${PATH}\n"
echo与printf之间的区别是printf没有办法自动换行
注意: $ , \ ,反单引号 `, 单引号,双引号
- $:会将$符号后面的字符识别的成一个变量,引用变量里面的值;
- \:会将所有特殊字符转义,会让特殊字符失去原有的含义;
- 反单引号:会将反单引号里面的内容当成一个命令来执行;`xxx`=$(xxx)
- 单引号:会让所有处于单引号里面的特殊字符失效;
- 双引号:会让所有处于双引号里面的特殊字符失效,除了$,反单引号,\在双引号里面保留自己的特殊含义。
②、查看多个变量的值
- set:查看所有的变量和函数
- declare:查看所有的变量和函数
- env:显示所有的全局变量
4、变量的定义
原则:直接使用,不需要变量声明
格式:变量名=变量的值
[root@server ~] # vim test2.sh#!/bin/bash# 定义变量 aa = 1# 定义变量 bb = "hello"# 定义变量 cc = "hello world"# 定义路径bak_dir = /data/backup
= 前后不能收空格
[root@server ~] # a= 3bash : 3 : command not found...[root@server ~] # b =5bash : b: command not found...
字符串类型建议使用双引好作为定界符引起,尤其是字符串中有空格
[root@server ~] # stu_name=zhang sanbash : san: command not found...[root@server ~] # stu_name="zhang san"[root@server ~] # stu_name='zhang san'
#系统自己自己定义的变量是环境变量
①、在命令行中定义:退出当前进程后该变量就失效,其他终端上无法使用该变量
- var='xiaoming2'
- var="`cmd`"
- var="$(cmd)"
②、在文件中定义:永久生效
如果是root用户:/root/.bashrc
如果是普通用户小明:/home/xiaoming/.bashrc
- 当前用户生效的文件
~/.bashrc 和 ~/.bash_profile(定义在家目录里)
- 所有用户生效的文件
/etc/bashrc/etc/profile/etc/profile.d/*.sh(加权限)
su和su -切换方式加载的文件不同:
[root@node13 ~] # su - studentLast login: Sun Sep 18 23 :06:43 CST 2022 on pts/0/etc/profile/etc/profile.d/name3.sh/etc/bashrc/home/student/.bash_profile/home/student/.bashrc/etc/bashrc[root@node13 ~] # su student/home/student/.bashrc/etc/bashrc/etc/profile.d/name3.sh
5、变量的分类
(1)局部变量(普通变量):
只在某个特定范围生效的变量,比如只能在当前进程中使用的变量,只在函数中使用的变量。
- 在命令行设置:在当前进程生效
- 在脚本文件中设置:在脚本文件中生效
- 在函数中定义普通变量: local var="value" ,只在当前函数中生效
- 在用户登录时加载的文件中设置:在脚本文件中无法使用
(2)全局变量(环境变量):
可以在创建他们的
shell
及其派生出来的子进程中使用(
su
切换用户的时候会读取新的环境变量)。
自定义环境变量和bash内置的环境变量。
-
自定义环境变量
export var 或 export var="value"declare - x var="value" , declare +x var 可 取消 环境变量
-
bash内置环境变量
var='xiaoming2'var="`cmd`"var="$(cmd)"
变量 | 说明 |
PATH | 命令的搜索路径,以冒号作为分隔符 |
HOME | 用户的家目录的路径,是cd命令的默认参数 |
COLUMNS | 命令行编辑模式下可使用命令的长度 |
HISTFILE | 命令历史的文件路径 |
HISTFILESIZE | 命令历史中包含的最大行数 |
HISTSIZE | history命令输出的记录数 |
LOGNAME | 当前用户的名字 |
SHELL | 当前使用的shell |
PWD | 当前的工作目录 |
-
位置参数和预定义变量
很多情况下,shell
脚本需要接受用户的输入,根据用户的输入来执行不同的操作。
从命令行传递给shell
脚本的参数又称为叫做位置参数,
shell
脚本会根据参数的位置使用不同的位置参数变量读取他们的值。
变量 | 说明 |
$#
|
命令行的参数的个数
|
$0
|
当前脚本的名称
|
$n
|
当前传递给脚本的第
n
个参数,比如
$1
表示脚本的第一个参数,
$2
表示脚本的第二个参 数……
|
${10} | 10以上的参数需要大花括号括起 |
$*
|
以
“
参数
1
参数
2
参数
3”
的形式返回所有参数的值
|
$@
|
以
“
参数
1” “
参数
2” “
参数
3”
的形式返回所有参数的值
|
$?
|
上一个命令的返回值状态码,
0
为成功
前一个命令、函数或者脚本的返回状态码,
$?
的返回值:
(1
)判断命令、函数或者脚本的 执行成功与否
(
2
)如果在脚本中调用了
"exit num"
,则会将这个数字返回给
$?
变量(
3
) 如果是在函数里,则通过“return num”
把这个数字以函数值的形式传给
$?
|
$$
|
返回本程序的进程
ID
(
PID
),不常用
|
$! | 上一个后台进程的PID |
当 $* 和 $ @ 没有被引用的时候,它们确实没有什么区别,都会把位置参数当成一个个体 , " $* " 会把所有位置参数当成一个整体(或者说当成一个单词),如果没有位置参数,则 " $* " 为空,如果有两个位置参数并且 IFS 为空 格时, " $* " 相当于 " $1 $2 "。
" $@ " 会把所有位置参数当成一个单独的字段,如果没有位置参数( $# 为 0 ),则 " $@ " 展开为空(不是空字符串,而是空列表),如果存在一个位置参数,则 " $@ " 相当于 " $1 " ,如果有两个参数,则 " $@ " 相当于 " $1 " " $2 " 等等。
[root@server ~]# set -- I am test command
[root@server ~]# for i in "$@"; do echo $i; done
I
am
test
command
[root@server ~]# for i in "$*"; do echo $i; done
I am test command
案例
[root@server ~] # cat t1.sh#!/bin/bashecho " 第 2 个位置参数是 : $2 "echo " 第 1 个位值参数是 : $1 "echo " 第 4 个位置参数是 : $4 "echo " 所有参数是 : $* "echo " 所有参数是 : $@ "echo " 参数的个数是 : $# "echo " 当前进程的 PID 值 : $$ "[root@server ~] # bash t1.sh 1 2 3 4 5第 2 个位置参数是 : 2第 1 个位值参数是 : 1第 4 个位置参数是 : 4所有参数是 : 1 2 3 4 5所有参数是 : 1 2 3 4 5参数的个数是 : 5当前进程的 PID 值 : 2986
6、取消变量
unset var
[root@server ~]# a=256
[root@server ~]# echo $a
256
[root@server ~]# unset a
[root@server ~]# echo $a
7、变量的作用域
全局变量:
全局变量定义在脚本中,也可以定义在函数中,作用范围:从定义的开始处到
shell
脚本结束或
者被显示的去除。
[root@server ~] #cat test5.sh#!/bin/bashfunc() # 定义函数{echo " $v1 "v1 = 200}v1 = 100funcecho " $v1 "[root@server ~] # bash test5.sh100200
函数内部定义全局变量
# 上例修改[root@server ~] # vim test5.sh#!/bin/bashfunc() # 定义函数{v2 = 200}funcecho " $v2 "[root@server ~] # bash test5.sh200
局部变量:
范围更小,仅限于某个程序段中,如:函数、
shell
等,通过
local
关键字定义,注意:函数的参
数也是局部变量
# 上例修改[root@server ~] # vim test5.sh#!/bin/bashfunc() # 定义函数{local v3 = 200 # 使用 local 关键字声明为局部变量}funcecho " $v3 "[root@server ~] # bash test5.sh
全局变量和局部变量区别
# 上例修改[root@server ~] # cat test5.sh#!/bin/bashfunc(){#输出全局变量 v1 的值echo "global variable v1 is $v1 "#定义局部变量 v1local v1 = 2#输出局部变量 v1 的值echo "local variable v1 is $v1 "}# 定义全局变量 v1v1 = 1# 调用函数func# 输出全局变量 v1 的值echo "global variable v1 is $v1 "
面试题:总结4中赋值方式
1 . 直接赋值 : name = "li si"2 .read 命令: read name3 . 使用位置参数 ( $1 $2 $3 …) : name = $14 . 命令输入 : name = $(whoami)