变量
程序 = 指令(只读) + 数据(数据存储的位置变量、列表、数组)
指令可通过位置变量调用,向脚本传递的数据
变量名 可引用的"命名的内存空间":取了名字的内存空间,用名字即可调用事先划分的内存空间
变量类型 变量内部存储的数据的类型
变量类型的作用
限定了存储空间
限定了存储格式
限定了参与的运算
变量的类型
字符型
数值型
整型
浮点型
变量的类型
强类型 定义变量时,必须指定变量的类型,参与的运算必须符合要求
调用未申明的变量,会报错
弱类型 定义变量时,不用指定变量的类型,参与运算时将自动进行隐式转换
直接赋值,直接引用 ,默认为字符型
var=value 表示把value值存储在var内存空间中
bash弱类型,解释型
1、不用申明,直接引用
2、参与运算,自动转换
变量的类型(按bash作用域划分)
本地变量 生效范围是当前shell的生命周期,对当前shell之外的其他shell进程和当前shell的子或父进程均无效。
环境变量 生效范围当前shell进程及其子shell进程,对其他shell无效。运行脚本时,脚本在当前shell的子shell中运行
局部变量 生效范围为当前shell进程中,只对某个代码片段(通常指)生效
位置变量 作用:向脚本参数,在让脚本脚本中可调用向脚本的参数
特殊变量 一般指的是内置变量,$?返回状态,$0返回状态, 指令可以通过位置变量调用,向脚本传递的参数
本地变量
生效范围是当前shell的生命周期,对当前shell之外的其他shell进程和当前shell的子或父进程均无效。
1)在当前shell定义的变量,对当前shell生效(当前shell进程的生命周期内)
1
2
3
4
5
|
[root@izpo45bh60h6bsz ~]
# tty #当前终端
/dev/pts/2
[root@izpo45bh60h6bsz ~]
# a=3 #在模拟终端2上定义一个本地变量
[root@izpo45bh60h6bsz ~]
# echo $a #可以显示其变量值
3
|
2)在当前shell中定义的变量,在新的shell中,不能生效
1
2
3
|
[root@izpo45bh60h6bsz ~]
# tty #另起一个shell,此时在模拟终端0上
/dev/pts/0
[root@izpo45bh60h6bsz ~]
# echo $a #显示其变量的值
|
3)当前shell的子shell进程中,变量也不会生效
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
[root@izpo45bh60h6bsz ~]
# pstree #显示当前系统上的进程树,
systemd --
#systemd为当前shell的父进程
├─sshd─┬─sshd───
bash
───pstree
# 当前shell的位置
[root@izpo45bh60h6bsz ~]
# bash #新启动一个子shell
[root@izpo45bh60h6bsz ~]
# pstree
systemd --
├─sshd─┬─sshd───
bash
───
bash
───pstree
#当前shell为子shell
[root@izpo45bh60h6bsz ~]
# echo $a #变量不会生效
[root@izpo45bh60h6bsz ~]
#
[root@izpo45bh60h6bsz ~]
# exit #退出当前shell,回到父shell
exit
[root@izpo45bh60h6bsz ~]
# pstree
systemd─
├─sshd─┬─sshd───
bash
───pstree
#回到当前shell进程
[root@izpo45bh60h6bsz ~]
# echo $a #变量生效
3
|
补充:
1
2
3
4
5
6
7
8
9
10
|
[root@izpo45bh60h6bsz ~]
# pidof bash ##当前bash的Pid号码
11423
[root@izpo45bh60h6bsz ~]
# echo $$ ##当前bash的Pid号码
11423
[root@izpo45bh60h6bsz ~]
# echo $SHLVL ##当前bash的层级
1
[root@izpo45bh60h6bsz ~]
# bash
defined
in
profile.d
/welcome
.sh 全局有效Welcome 0 your home
/root
[root@izpo45bh60h6bsz ~]
# echo $SHLVL ##当前bash的层级
2
|
环境变量
生效范围当前shell进程及其子shell进程,对其他shell无效
注释
1)在当前shell定义的变量,对当前shell及子shell有效
1
2
3
4
5
6
7
8
9
10
|
[root@izpo45bh60h6bsz ~]
# tty #当前终端
/dev/pts/2
[root@izpo45bh60h6bsz ~]
# declare -x name=pidof #定义环境变量
[root@izpo45bh60h6bsz ~]
# echo $name
pidof
[root@izpo45bh60h6bsz ~]
# bash
[root@izpo45bh60h6bsz ~]
# echo $name
pidof
[root@izpo45bh60h6bsz ~]
# exit
exit
|
2)在当前shell中定义的变量,在新的shell中,不能生效
1
2
3
4
5
|
[root@izpo45bh60h6bsz ~]
# tty #另起一个shell,此时在模拟终端0上
/dev/pts/0
[root@izpo45bh60h6bsz ~]
# echo $name
[root@izpo45bh60h6bsz ~]
#
|
位置变量
$1,$2,.... 调用每个向脚本传递的参数
1
2
3
4
5
6
7
8
9
10
11
12
|
[root@izpo45bh60h6bsz ~]
# nano psvar.sh
#!/bin/bash
echo
"\$1: $1"
echo
"\$2: $2"
[root@izpo45bh60h6bsz ~]
# chmod +x psvar.sh
[root@izpo45bh60h6bsz ~]
# ls -l psvar.sh
-rwxr-xr-x 1 root root 43 Aug 1 15:10 psvar.sh
[root@izpo45bh60h6bsz ~]
# ./psvar.sh tom jerry
$1: tom
$2: jerry
|
特殊变量
$0:表示命令本身,$?命令的执行状态结果
1
2
3
4
5
|
# echo 'echo "\$0: $0"' >> psvar.sh
[root@izpo45bh60h6bsz ~]
# ./psvar.sh tom jerry
$1: tom
$2: jerry
$0: .
/psvar
.sh
|
本地变量
赋值:把value表示的值 存储在name变量的内存空间中
1
|
# name='value'
|
name 内存空间的名字
= 赋值符号
value 值
‘ ’或 " " 引用符号
引用实现赋值:
纯文本引用:将文本字符赋值给变量
变量的引用:将变量的值赋值给另一个变量
命令的引用:将命令的执行结果赋值给变量:
混合使用
注意:赋值时,如果值有空格必须加引号
变量引用实现赋值
1
2
3
4
5
6
|
[root@izpo45bh60h6bsz ~]
# username=pig
[root@izpo45bh60h6bsz ~]
# echo $name
[root@izpo45bh60h6bsz ~]
# name=$username
[root@izpo45bh60h6bsz ~]
# echo $name
pig
|
命令引用实现赋值
1
2
3
4
5
|
[root@izpo45bh60h6bsz ~]
# pwd
/root
[root@izpo45bh60h6bsz ~]
# name=`pwd`
[root@izpo45bh60h6bsz ~]
# echo $name
/root
|
混合使用
1
2
3
|
# filename=`date +%F-%H-%M-%S`
# echo $filename
2017-08-01-15-41-45
|
值有空格,在赋值时需要加引号
1
2
3
4
5
|
[root@izpo45bh60h6bsz ~]
# name=tom obama
-
bash
: obama:
command
not found
[root@izpo45bh60h6bsz ~]
# name="tom obama"
[root@izpo45bh60h6bsz ~]
# echo $name
tom obama
|
变量引用 ,$name, ${name},通常用$name。当变量名与能作为变量名使用的字符串连在一起使用时,以免把整个名字当作变量,必须加 {}
' ' 强引用 其中的变量引用,不会被替换为变量中所存储的值
" " 弱引用 其中的变量引用,会被替换为变量中 所存储的值
1、何时应该使用${name}
1
2
3
4
5
|
# animal=pig
# echo "there are some $animals" #把整个名字当作变量。由于此变量未定义,故为空
there are some
# echo "there are some ${animal}s"
there are some pigs
|
2、强引用和弱引用的区别
1
2
3
4
|
[root@izpo45bh60h6bsz ~]
# echo "$animal" 变量会被替换
pig
[root@izpo45bh60h6bsz ~]
# echo '$animal' 变量不会被替换
$animal
|
显示所有本地变量和环境变量: set
变量销毁:在shell终止时,变量会被销毁。在shell终止前销毁变量: unset name
1
2
3
4
5
6
7
|
[root@izpo45bh60h6bsz ~]
# name=pika
[root@izpo45bh60h6bsz ~]
# echo $name
pika
[root@izpo45bh60h6bsz ~]
# unset name
[root@izpo45bh60h6bsz ~]
# echo $name
[root@izpo45bh60h6bsz ~]
#
|
环境变量
赋值 把value表示的值 存储在name变量的内存空间中
1
2
3
4
5
6
7
8
|
方法一
# declare -x name='value'
方法二
# export name='value'
方法三
# name=value
# declare -x name
# export name
|
引用
1
|
# $name,${name}
|
显示所有的环境变量
1
2
3
|
# export
# env
# printenv
|
其中大写的是环境变量: 定义bash工作环境
bash有许多内建的环境变量:对于大写的变量,不要直接赋值,定义环境变量时,避免bash内建的环境变量,否则会改变bash的工作行为。
PATH,SHELL,UID,PS1,HISTSIZE,HOME,PWD,OLDPWD
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
[root@izpo45bh60h6bsz ~]
# echo $PATH #bash解析命令所依赖的变量
/usr/local/nginx/sbin
:
/usr/local/sbin
:
/usr/local/bin
:
/usr/sbin
:
/usr/bin
:
/root/bin
[root@izpo45bh60h6bsz ~]
# echo $SHELL #当前shell环境
/bin/bash
[root@izpo45bh60h6bsz ~]
# echo $UID #当前有效用户的ID号码
0
[root@izpo45bh60h6bsz ~]
# echo $PS1 #定义命令提示符字串
[\u@\H \W]\$
[root@izpo45bh60h6bsz ~]
# echo $HISTSIZE #显示命令条数
1000
[root@izpo45bh60h6bsz ~]
# echo $HOME #显示当前用户的家目录位置
/root
[root@izpo45bh60h6bsz ~]
# echo $PWD #显示当前所处的目录
/root
[root@izpo45bh60h6bsz ~]
# echo $OLDPWD #显示最近一次切换的目录
[root@izpo45bh60h6bsz ~]
#
|
变量销毁:unset
1
|
unset
|
变量命名的法则
1、不能使用关键字和保留字,if,for
2、只能使用数字、字母及下划线,不能以数字开头
3、尽量做到,见名知义
1
2
|
totalweight --> totalWeight 避免全部大写
--> total_weight 或者用连字符
|
4、尽量避免 _ 开头
5、尽量避免 全大写
文件名命名的法则
1、区分大小写
file1, File1, FILE1是不同的文件
2、不使用特殊字符
/:根目录,路径分隔符
3、长度小于255个字符
4、以.开头的文件,均为隐藏文件
LInux哲学思想
1、一切皆文件
2、组合小程序
3、不交互
4、文本编辑配置
常量、只读变量:定义变量后,变量不允许改变。只能等到shell进程终止时,才随之消亡
赋值
1
2
3
4
|
方法一
readonly
name
方法二
declare
-r name
|
查看
1
2
3
4
5
|
[root@izpo45bh60h6bsz ~]
# declare -r name='obama' ##定义只读变量
[root@izpo45bh60h6bsz ~]
# readonly -p ##显示所有的只读变量
declare
-ir PPID=
"11423"
declare
-ir UID=
"0"
declare
-r name=
"obama"
|
注释
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
[root@izpo45bh60h6bsz ~]
# name=obama
[root@izpo45bh60h6bsz ~]
# echo $name
obama
[root@izpo45bh60h6bsz ~]
# readonly name
[root@izpo45bh60h6bsz ~]
# name=jerry
-
bash
: name:
readonly
variable
[root@izpo45bh60h6bsz ~]
# unset name
-
bash
:
unset
: name: cannot
unset
:
readonly
variable
[root@localhost ~]
# name="jerry obame"
[root@localhost ~]
# echo $name
jerry obame
[root@localhost ~]
# declare -r name
[root@localhost ~]
# name=hello
-
bash
: name:
readonly
variable
[root@localhost ~]
# unset name
-
bash
:
unset
: name: cannot
unset
:
readonly
variable
|
局部变量
用于函数体中
位置变量
指令可以通过位置变量调用,向脚本传递的参数
变量
1
2
|
$1,$2,...对应调用 第1 第2 第3...参数
$0 命令本身
|
调用传递给脚本的所以的参数
$* 表示调用时,将传递的参数当作一个字串
$@ 每个参数当作独立的字串
$# 传递给脚本的参数的个数
1
2
3
4
5
6
7
8
9
|
[root@izpo45bh60h6bsz ~]
# cat posvar.sh
#!/bin/bash
echo
"\$1: $1"
echo
"\$2: $2"
echo
"\$3: $3"
echo
"\$*: $*"
echo
"\$@: $@"
echo
"\$#: $#"
echo
"\$0: $0"
|
1
2
3
4
5
6
7
8
|
[root@izpo45bh60h6bsz ~]
# ./posvar.sh tom jerry blair
$1: tom
$2: jerry
$3: blair
$*: tom jerry blair
$@: tom jerry blair
$
#: 3
$0: .
/posvar
.sh
|
换港操作符 shift [n] 默认踢一个
1
2
3
4
5
6
7
8
9
10
11
|
[root@izpo45bh60h6bsz ~]
# cat posvar.sh
#!/bin/bash
echo
"\$1: $1"
shift
echo
"\$1: $1"
shift
2
echo
"\$1: $1"
echo
"\$*: $*"
echo
"\$@: $@"
echo
"\$#: $#"
echo
"\$0: $0"
|
1
2
3
4
5
6
7
8
|
[root@izpo45bh60h6bsz ~]
# ./posvar.sh tom jerry blair mariadb
$1: tom
$1: jerry
$1: mariadb
$*: mariadb
$@: mariadb
$
#: 1
$0: .
/posvar
.sh
|
向脚本传递参数,做文本行的统计
1
2
3
4
|
# vim posvar.sh
#!/bin/bash
countlines=`
cat
$1 |
wc
-l`
echo
"$1 has $countlines lines"
|
1
2
|
# ./posvar.sh /etc/fstab
/etc/fstab
has 10 lines
|