1.认识shell变量
1.1什么是shell变量
当你开始学习一门编程语言时,首先,你需要了解的就是此语言中的变量,变量就是程序设计语言中一个可以变化的量,当然,可变化的是变量的值。从本质上来讲,变量就是在程序中保存用户数据的一块内存空间,而变量名就是这块内存空间的地址。
在程序的执行过程中,保存数据的内存空间的内容可能会不断地发生变化,但是,代表内存地址的变量名却保持不变。
1.2变量的命名规则
在shell中,变量名可由字母,数字或者下划线组成,并且只能由字母或者下划线开头。对于变量名的长度没有明确规定。但是,为了方便使用还是根据自身要来定义变量名的长度,并且变量名要见名知意。
变量名的命令规则:
1.首个字符必须是大小写字母(a-zA-Z)或者下划线(_)
2.中间不能有空格,可以使用下划线
3.不能使用标点符号
4.不能使用bash里的关键字(使用help命令来查看保留关键字)
1.3.变量的类型
shell是一种动态类型语言和弱类型语言,即在shell中,变量的数据类型无需显示声明,变量的数据类型会根据不同的操作有所变化。准确的说,shell中的变量是不分数据类型的,统一的按照字符串存储,但是根据变量的上下文环境,允许程序执行一些不同的操作。
动态语言和静态语言。
1:动态类型语言:动态类型语言是指在运行期间才去做数据类型检查的语言,也就是说,在用动态类型的语言编程时,永远也不用给任何变量指定数据类型,该语言会在你第一次赋值给变量时,在内部将数据类型记录下来。Python和Ruby就是一种典型的动态类型语言,其他的各种脚本语言如VBScript也多少属于动态类型语言。
2:静态类型语言:静态类型语言与动态类型语言刚好相反,它的数据类型是在编译其间检查的,也就是说在写程序时要声明所有变量的数据类型,C/C++是静态类型语言的典型代表,其他的静态类型语言还有C#、JAVA等。强类型语言和弱类型语言
3:强类型定义语言:强制数据类型定义的语言。也就是说,一旦一个变量被指定了某个数据类型,如果不经过强制转换,那么它就永远是这个数据类型了。举个例子:如果你定义了一个整型变量a,那么程序根本不可能将a当作字符串类型处理。强类型定义语言是类型安全的语言。
4:弱类型定义语言:数据类型可以被忽略的语言。它与强类型定义语言相反, 一个变量可以赋不同数据类型的值。强类型定义语言在速度上可能略逊色于弱类型定义语言,但是强类型定义语言带来的严谨性能够有效的避免许多错误。另外,“这门语言是不是动态语言”与“这门语言是否类型安全”之间是完全没有联系的!例如:Python是动态语言,是强类型定义语言(类型安全的语言);VBScript是动态语言,是弱类型定义语言(类型不安全的语言); JAVA是静态语言,是强类型定义语言(类型安全的语言)。
强类型语言是指需要进行变量/对象类型声明的语言,一般情况下需要编译执行。例如C/C++/Java/C#弱类型语言是指不需要进行变量/对象类型声明的语言,一般情况下不需要编译(但也有编译型的)。例如:PHP/ASP/Ruby/Python/Perl/ABAP/SQL/JavaScript/Unix/Shell等等
1.静态类型定义语言
一种在编译时,数据类型是固定的语言。大多数静态类型定义语言强制这一点,它要求你在使用所有变量之前要声明它们的数据类型。Java和C是静态类型定义语言。
2.动态类型定义语言
一种在执行期间才去发现数据类型的语言,与静态类型定义相反。VBScript和Python是动态类型定义的,因为它们是在第一次给一个变量赋值的时候找出它的类型的。
3.强类型定义语言
一种总是强制类型定义的语言。Java和Python是强制类型定义的。如果你有一个整数,如果不显示地进行转换,你不能将其视为一个字符串
4.弱类型定义语言
一种类型可以被忽略的语言,与强类型定义相反。可以将字符串 ‘12’和整数 3 进行连接得到字符串’123’,然后可以把它看成整数123,而不需要显示转换。
写一个shell脚本,演示shell的数据类型
#! /bin/bash
#定义变量X,并且赋值为123
x=123
#变量x加1
let "x += 1"
#输出变量x的值
echo "x = $x"
#显示空行
echo
#替换x中的1位abc,并且将值赋给变量y
y={x/1/abc}
#输出y的值
echo "y = $y"
#声明变量y
declare -i y
#输出变量y的值
echo "y = $y"
给脚本加执行权限,执行看执行结果
[root@bogon ~]# chmod +x sh1.sh
[root@bogon ~]# ./sh1.sh
x = 124
y = abc24
y = abc24
1.4变量的定义
在shell中,通常情况下用户可以直接使用变量,不用提前定义,当用户第一次使用某个变量名时,实际上就同时定义了此变量,在变量的作用域内用户都可以使用该变量。
变量定义:
变量名=变量值
#! /bin/bash
#定义变量a,且a的值为1
a=1
echo "a = $a"
#定义变量b
b="hello"
echo "b = $b"
#定义变量c
c="hello world"
echo "c = $c"
添加执行权限,查看执行结果
[root@bogon ~]# chmod +x sh2.sh
[root@bogon ~]# ./sh2.sh
a = 1
b = hello
c = hello world
注意事项:
1.=号前后不能出现一端有空格,一端没空格,或者两端都有空格
[root@bogon ~]# a =1
-bash: a: 未找到命令
[root@bogon ~]# a= 1
-bash: 1: 未找到命令
[root@bogon ~]# a=1
[root@bogon ~]# echo $a
1
[root@bogon ~]# b = 2
[root@bogon ~]# b=2
[root@bogon ~]# echo $b
2
2.字符串类型建议用引号括起来,尤其是有特殊字符或者是有空格
[root@bogon ~]# d=hello
[root@bogon ~]# e="hello"
[root@bogon ~]# f=hello world
-bash: world: 未找到命令
[root@bogon ~]# f="hello world"
[root@bogon ~]# echo $d
hello
[root@bogon ~]# echo $e
hello
[root@bogon ~]# echo $f
hello world
1.5自定义变量和环境变量及只读变量
(1)自定义变量
1.定义变量:变量名=变量值 ;变量名遵循变量命名法则,使用字母,数字,下划线,只能以字母下划线开头,严格区分大小写。
2.引用变量: “$变量名"或者” ${变量名}"
3.查看变量:echo $变量名 set (所有变量:包括自定义变量和环境变量)
4.取消变量: unset 变量名
取消变量时常用的选项是-f和-v;其中-f是指取消的是函数,-v取消的是变量;如果使用时没指定选项,首先先尝试取消变量,其次在尝试取消函数。
注意:只读变量不能取消
5.作用范围: 仅在当前shell环境中有效
linux的set命令详解
set命令作用主要是显示系统中已经存在的shell变量,以及设置shell变量的新变量值。使用set更改shell特性时,符号"+"和"-"的作用分别是打开和关闭指定的模式。set命令不能够定义新的shell变量。如果要定义新的变量,可以使用declare命令以变量名=值的格式进行定义即可。
语法
set(选项)(参数)
选项
-a:标示已修改的变量,以供输出至环境变量。
-b:使被中止的后台程序立刻回报执行状态。
-c:转向所产生的文件无法覆盖已存在的文件。
-d:shell预设会用杂凑表记忆使用过的指令,以加速指令的执行。使用-d参数可取消。
-e:若指令传回值不等于0,则立即退出shell。
-f:取消使用通配符。
-h:自动记录函数的所在位置。
-h shell:可利用"!"加<指令编号>的方式来执行history中记录的指令。
-k:指令所给的参数都会被视为此指令的环境变量。
-l:记录for循环的变量名称。
-m:使用监视模式。
-n:只读取指令,而不实际执行。
-p:启动优先顺序模式。 -p:启动-p参数后,执行指令时,会以实际的文件或目录来取代符号连接。
-t:执行完随后的指令,即退出shell。
-u:当执行时使用到未定义过的变量,则显示错误信息。
-v:显示shell所读取的输入值。
-x:执行指令后,会先显示该指令及所下的参数。
参数
取消某个set曾启动的参数。
linux的set命令实例
使用declare命令定义一个新的环境变量"mylove",并且将其值设置为"visual c++",输入如下命令:
declare mylove='visual c++' #定义新环境变量
再使用set命令将新定义的变量输出为环境变量,输入如下命令: set -a mylove #设置为环境变量
执行该命令后,将会新添加对应的环境变量。用户可以使用env命令和grep命令分别显示和搜索环境变量"mylove",输入命令如下:
env | grep mylove #显示环境变量值
此时,该命令执行后,将输出查询到的环境变量值。
(2)环境变量
1、Shell定义的环境变量
在当前shell环境和子shell起作用
Shell在开始执行的时候就已经定义了一些与系统工作环境有关的变量,用户还可以重新定义这些变量。 常用的shell环境变量有以下几种:1)HOME:用于保存用户主目录的完全路径名。
2)PATH:用于保存用冒号分隔的目录路径名,shell将按PATH变量中给出的顺序搜索这些目录,找到的第一个与命令名称一致的可执行文件将被执行。
3)SHELL:当前用户使用的Shell
4)UID:当前用户的UID
5)LOGNAME:当前用户的登录名
6)HOSTNAME:主机名称
2、查看环境变量
Linux系统中set 、env 和 export 命令都可以查看环境变量。
1)set命令显示当前shell的变量,包括当前用户的变量,set主要用来设置sh的参数与选项
2)env命令显示当前用户的变量,env用来在构建的环境中运行命令
3)export命令显示当前导出成用户变量的shell变量
每个shell都有特有的变量set显示的变量,这个和用户变量是不同的,当前用户变量和用什么shell无关,不管用户使用什么shell都会存在,比如HOME,SHELL等这些变量。
但shell本身的变量不同,比如BASH_ARGC,BASH等,这些变量只有set才会显示,是bash特有的。export不加参数的时候,显示哪些变量被导出成了用户变量,因为一个shell本身的变量可以通过
export “导出”变成一个用户变量。3、Linux系统下环境变量的设置
如果想将一个路径加入到 $PATH 中,可以有几种方法,例如将/tmp/xie路径加入到 $PATH 变量中。
1)控制台中设置 (只对当前shell有效):PATH=$PATH:/tmp/xie
2)修改当前家目录下的 .bashrc 文件 (只对当前用户有效):vim~/.bashrc
在最末尾加入source .bashrc或者.bashrc
export PATH=$PATH:/tmp/xie
3)修改/etc/bashrc 文件 (针对所有用户有效):vim/etc/bashrc
在最末尾加入source /etc/bashrc或者. /etc/bashrc
(3)只读变量
只读变量的值不能被更改,不能取消,想要取消只能,重新启动当前机器
定义只读变量的方法:
1.使用关键字readonly
eg: readonly v=123
2.通过declare -r命令
eg: declare -r w=‘567’
查看只读变量: 通过readonly查看所有的只读变量
[root@bogon ~]# readonly v=123
[root@bogon ~]# declare -r w='567'
[root@bogon ~]# readonly
declare -r BASHOPTS="checkwinsize:cmdhist:expand_aliases:extglob:extquote:force_fignore:histappend:interactive_comments:login_shell:progcomp:promptvars:sourcepath"
declare -ir BASHPID
declare -r BASH_COMPLETION_COMPAT_DIR="/etc/bash_completion.d"
declare -ar BASH_REMATCH='()'
declare -ar BASH_VERSINFO='([0]="4" [1]="2" [2]="46" [3]="1" [4]="release" [5]="x86_64-redhat-linux-gnu")'
declare -ir EUID="0"
declare -ir PPID="2978"
declare -r SHELLOPTS="braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor"
declare -ir UID="0"
declare -r v="123"
declare -r w="567"
想让环境变量永久生效的方式是,修改相关的配置文件。
Bash的初始化文件有:/etc/profile、~/.bash_profile,
~/.bash_login、~/.profile、~/.bashrc、/etc/bashrc
虚线方向是被调用的配置文件,实线是主线流程。
1./etc/profile 存放的是一些全局变量,不管哪个用户,登录系统时都会读取该文件。通常设置一些shell的环境变量,例如:PATH,USER,HOSTNAME等。
2.~/.bash_profile 每个用户都可以使用该文件输入属于自己专属shell信息,当用户登录时,该文件仅执行一次。
[root@bogon ~]# vim ~/.bash_profile
# .bash_profile
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
# User specific environment and startup programs
PATH=$PATH:$HOME/bin
export PATH
3.~/.bashrc 该文件包含专用于你的bash shell的bash信息,当登录时以及每次打开新的shell时,该文件就会被读取。
[root@bogon ~]# vim ~/.bashrc
# .bashrc
# User specific aliases and functions
alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'
# Source global definitions
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi
4./etc/bashrc 为每一个运行shell的用户执行此文件,当bash shell 被打开时,该文件被打开。
区别: bash_profile只在会话开始的时候(登录时)读取一次,而bashrc则是每打开一次终端都会加载一次。
配置文件作用
(1)登录Linux先启动系统配置文件/etc/profile,并从/etc/profile.d目录的配置文件中搜索shell的设置,为系统的每一个用户设置环境信息。
(2)用户配置文件~/.bash_profile
每个用户专用于自己使用的shell信息,仅用户登录时执行一次。默认情况下,此文件通过脚本执行同目录下用户的.bashrc文件。
(3)~/.bashrc文件包含专用于用户bash shell 的shell
信息,登录及每次打开新的shell时都会执行。里面又会调用/etc/bashrc.
上述文件的读取顺序:
**1)配置文件的执行顺序**
/etc/profile-->/etc/profile.d/*.sh-->~/.bash_profile-->/etc/bashrc-->~./.bashrc
**2)登录式shell的配置文件执行顺序**
(清除所有变量,通过文件重新读入)
**判断登录式shell:**
a.直接通过终端输入账号密码登录
b.使用“su -UserName”切换的用户
执行顺序:(影响该shell的配置文件)
/etc/profile-->/etc/profile.d/*.sh-->~/.bash_profile-->~/.bashrc-->/etc/bashrc
**3)非登录式shell配置文件执行顺序**
(会继承上一个shell的全部变量):
**如何判断非登录式的shell:**
a.su UserName
b.图形界面下打开终端
c.执行脚本(进入子shell)
d.任何其他的bash实例
执行顺序:(影响该shell的配置文件)
~./.bashrc-->/etc/bashrc-->/etc/profile.d/*.sh