Shell变量
1、变量命名规则
- 变量名称可以由字母、数字和下划线组成,但是不能以数字开头。
- 变量用等号连接值时,等号两侧不能有空格。
- 变量的值如果有空格,则需要用单引号或者双引号(英文状态下)引起来。
- 在变量中可以使用 \作为转义字符。
- 在bash中,默认的数值类型为字符型,如果需要做数值运算时,需要转化为数值类型再计算。
- 如果是把命令的结果作为变量的值赋予变量,则需要使用
反引号或$()
包含命令。 - 如果需要增加变量的值,则可以进行变量值的叠加,不过变量需要使用双引号包含
“$变量名”
或用${变量名}
系统环境变量名称一般用为大写
,以示区别。
2、变量分类
Linux Shell中的变量大致可以分为两大类:
- 用户自定义变量:变量名可以自己定义,变量作用范围也可以自己定义。
- 系统变量:变量名不可以自己定义,变量作用范围也不可以自己定义,都已经固定好了,通常包含三种变量
- 环境变量:主要用来保存与操作系统环境有关的变量。
- 预定义变量:已经定义好的变量。
- 位置参数变量:用来向脚本中传递数据和参数的。
3、具体应用
主要按着变量的分类进行具体应用。
3.1、用户自定义变量
用户自定义变量也叫作本地变量,只能在当前shell中使用 。
具体用法
1.0 变量定义
语法
变量名=变量值
注:静态变量(只读变量)定义使用
readonly 变量,而且不能被unset
案例
[root@root test02]# best=10
2.0 变量调用
语法
$变量值
案例
[root@root test02]# echo $best
10
3.0 变量查看
语法
set
注:可以查看系统中定义的所有变量
案例
查看系统中所有的变量
[root@root test02]# set
BASH=/bin/bash
BASHOPTS=checkwinsize:cmdhist:expand_aliases:extquote:force_fignore:histappend:hostcomplete:interactive_comments:login_shell:progcomp:promptvars:sourcepath
BASH_ALIASES=()
BASH_ARGC=()
BASH_ARGV=()
BASH_CMDS=()
BASH_LINENO=()
BASH_SOURCE=()
BASH_VERSINFO=([0]="4" [1]="2" [2]="46" [3]="2" [4]="release" [5]="x86_64-redhat-linux-gnu")
BASH_VERSION='4.2.46(2)-release'
CLASSPATH=.:/usr/java/jdk1.8.0_221-amd64/lib:/usr/java/jdk1.8.0_221-amd64/jre/lib
COLUMNS=158
DIRSTACK=()
EUID=0
GROUPS=()
HISTCONTROL=ignoredups
HISTFILE=/root/.bash_hist
4.0 变量删除
语法
unset 变量名
案例
删除创建的变量best
[root@root test02]# unset best
[root@root test02]# echo $best
3.2、环境变量
环境变量:主要用来保存与操作系统环境有关的变量。其变量名和作用范围固定不变。它不仅可以在当前shell中生效,也可以在当前shell的子shell中生效,作用范围比较广泛。
具体用法
1.0 可以通过pstree查看当前shell的级别
语法
pstree
案例
查看当前shell的级别
root@root test02]# cat /etc/shells
/bin/sh
/bin/bash
/usr/bin/sh
/usr/bin/bash
#切换到sh
[root@root test02]# sh
sh-4.2# pstree
systemd─┬─AliSecGuard───6*[{AliSecGuard}]
├─AliYunDun───24*[{AliYunDun}]
├─AliYunDunUpdate───5*[{AliYunDunUpdate}]
├─BT-Panel───{BT-Panel}
├─BT-Task─┬─python
│ └─9*[{BT-Task}]
├─2*[agetty]
├─aliyun-service───7*[{aliyun-service}]
├─assist_daemon───7*[{assist_daemon}]
├─atd
├─auditd───{auditd}
├─chronyd
├─containerd───10*[{containerd}]
├─crond
├─dbus-daemon
├─dhclient
├─dockerd───10*[{dockerd}]
├─firewalld───{firewalld}
├─java───28*[{java}]
├─mysqld_safe───mysqld───22*[{mysqld}]
├─polkitd───6*[{polkitd}]
├─rsyslogd───2*[{rsyslogd}]
#可以看出来sh是子
├─sshd─┬─sshd───bash───bash───sh───pstree
│ └─sshd───sftp-server
├─systemd-journal
├─systemd-logind
├─systemd-udevd
└─tuned───4*[{tuned}]
2.0 声明环境变量
语法
export 变量名=变量值
功能描述:将 shell 变量输出为环境变量
当变量名为环境变量时,一般大写,以示区别。
注: 环境变量一般都配置在/etc/profile中
案例
配置Java环境
[root@root test02]# vim /etc/profile
JAVA_HOME=/usr/java/jdk1.8.0_221-amd64
CLASSPATH=%JAVA_HOME%/lib;%JAVA_HOME%/jre/lib
PATH=$JAVA_HOME/bin;$JAVA_HOME/jre/bin
export PATH CALSSPATH JAVA_HOME
3.0 配置文件生效
语法
source 配置文件名
让配置文件立刻生效
案例
让上面配置的java环境生效
[root@root test02]# source /etc/profile
注:
常见问题:
错误描述:linux安装了java8以后,配置了java环境,重新打开以后出现如下错误:
Welcome to Alibaba Cloud Elastic Compute Service !
-bash: fg: no job control
-bash: /usr/java/jdk1.8.0_221-amd64/jre/bin: Is a directory
由于出现了这种错误,一些常用的liunx命令就不能正常使用,例如 ls vim cat等
[root@root ~]# cd /
[root@root /]# cd home/
[root@root home]# ls
-bash: ls: command not found
[root@root home]# cd /home/itbestboy/
[root@root itbestboy]# ls
-bash: ls: command not found
[root@root itbestboy]# ll
-bash: ls: command not found
[root@root itbestboy]# cat apache-tomcat-9.0.48
-bash: cat: command not found
[root@root itbestboy]# vim /etc/profile
-bash: vim: command not found
[root@root itbestboy]#
此时可以使用这个命令以达到正常使用命令
export PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
效果
[root@root itbestboy]# ll
total 186528
drwxr-xr-x 9 root root 4096 Jul 3 22:25 apache-tomcat-9.0.48
-rw-r--r-- 1 root root 11489338 Jul 3 20:49 apache-tomcat-9.0.48.tar.gz
-rw-r--r-- 1 root root 179505388 Jul 3 20:50 jdk-8u221-linux-x64.rpm
[root@root itbestboy]#
但这个只是暂时性的,如果断开连接,则需要重新配置这个命令,比较麻烦,此时需要更改jdk的一些配置,就可以长久生效
[root@root itbestboy]# vim /etc/profile
#值使我之前的配置
JAVA_HOME=/usr/java/jdk1.8.0_221-amd64
CLASSPATH=%JAVA_HOME%/lib;%JAVA_HOME%/jre/lib
PATH=$JAVA_HOME/bin;$JAVA_HOME/jre/bin
export PATH CALSSPATH JAVA_HOME
#现在更改为如下配置
JAVA_HOME=/usr/java/jdk1.8.0_221-amd64
JRE_HOME=$JAVA_HOME/jre
CLASSPATH=.:$JAVA_HOME/lib:$JRE_HOME/lib
PATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH
export JAVA_HOME JRE_HOME CLASSPATH PATH
然后使用以下命令,使配置文件生效
source /etc/profile
此时断开连接重启,也可以正常输入命令
Welcome to Alibaba Cloud Elastic Compute Service !
[root@root ~]# cd /home/
[root@root home]# ll
total 8
drwxr-xr-x 3 root root 4096 Jul 3 22:25 itbestboy
drwx------ 2 www www 4096 Jul 3 23:28 www
[root@root home]# cd itbestboy/
[root@root itbestboy]# ll
total 186528
drwxr-xr-x 9 root root 4096 Jul 3 22:25 apache-tomcat-9.0.48
-rw-r--r-- 1 root root 11489338 Jul 3 20:49 apache-tomcat-9.0.48.tar.gz
-rw-r--r-- 1 root root 179505388 Jul 3 20:50 jdk-8u221-linux-x64.rpm
[root@root itbestboy]#
4.0 查看变量的值
语法
echo $变量名
案例
查看配置的jdk的部分信息
[root@root test02]# echo $JAVA_HOME
/usr/java/jdk1.8.0_221-amd64
[root@root test02]# echo $CLASSPATH
.:/usr/java/jdk1.8.0_221-amd64/lib:/usr/java/jdk1.8.0_221-amd64/jre/lib
5.0 查看环境变量
语法
env
注:只能查看环境变量,其他的变量不可以查看
案例
查看当前系统中的环境变量
[root@root test02]# env
HOSTNAME=root
HISTSIZE=1000
.............................................................
USER=root
JRE_HOME=/usr/java/jdk1.8.0_221-amd64/jre
PATH=/usr/java/jdk1.8.0_221-amd64/bin:/usr/java/jdk1.8.0_221-amd64/jre/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
JAVA_HOME=/usr/java/jdk1.8.0_221-amd64
CLASSPATH=.:/usr/java/jdk1.8.0_221-amd64/lib:/usr/java/jdk1.8.0_221-amd64/jre/lib
............................................................
............................................................
6.0 删除变量
语法
unset 变量名
案例
删除刚才设置的jdk环境部分
[root@root test02]# unset JAVA_HOME
7.0 设置系统变量
一般在linux中我们会用一些常用的命令,比如cd ls等,这些命令之所以能够直接使用,是因为在系统中已经定义好了,所以我们也可以在系统中定义一些常用的命令,即定制化。该操作主要涉及的地方是PATH,其中$PATH中主要是一些路径,当有多个路径时中间用冒号:隔开。
语法
PATH ="$PATH":/路径
案例
当我们在执行.sh文件时需要使用绝对路径执行或者使用./××.sh
,有时候这样比较麻烦,此时我们可以把.sh文件的路径加入PATH中,就可以像调用平时的命令一样直接使用。
例如,把test01.sh文件的路径加入PATH中
#刚开始直接调用,找不到
root@root test02]# test01.sh
bash: test01.sh: command not found
#加入PATH
[root@root test02]# PATH="$PATH":/home/itbestboy/test02/
#查看此时的系统环境
[root@root test02]# echo $PATH
/usr/java/jdk1.8.0_221-amd64/bin:/usr/java/jdk1.8.0_221-amd64/jre/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/home/itbestboy/test02/
#直接调用
[root@root test02]# test01.sh
10秒倒计时开始
10
9
8
7
6
5
4
3
2
1
0
10秒倒计时结束
[root@root test02]#
3.3、预定义变量
预定义参数简言之就是 事先已经定义好的变量,可以直接在 shell 脚本中使用。
预定义变量 | 作用 |
---|---|
$$ | 当前进程的进程号(PID) |
$! | 后台运行的最后一个进程的进程号(PID) |
$? | 最后一次执行的命令的返回状态。 如果这个变量的值为 0,证明上一个命令正确执行; 如果这个变量的值为非 0(具体是哪个数,由命令自己来决定),则证明上一个命令执行不正确。 |
案例
查看test01.sh的进程信息
[root@root test02]# vim test01.sh
echo "当前进程的id=$$"
./test01.sh $
echo "后台最后一个进程的id=$!"
echo "执行的值=$?"
[root@root test02]# test01.sh
当前进程的id=25994
3.4、位置参数变量
当我们执行一个 shell 脚本时,如果希望获取到命令行的参数信息,就可以使用到位置参数变量,比如 : ./myshell.sh 100 200 , 这个就是一个执行 shell 的命令行,可以在 myshell 脚本中获取到参数信息。
位置参数变量 | 作用 |
---|---|
$n | n 为数字, $0 代表命令本身,$1-$9 代表第一到第九个参数,十以上的参数,十以上的参数需要用大括号包含,如${10} |
$* | 代表命令行中所有的参数,$*把所有的参数看成一个整体 |
$@ | 代表命令行中所有的参数,不过$@把每个参数区分对待 |
$# | 代表命令行中所有参数的个数 |
案例
编写一个脚本,脚本中获取到命令行的各个参数信息
[root@root test02]# vim test01.sh
#!/bin/bash
echo "$0 $1 $2"
echo "$*"
echo "$@"
echo "参数总个数为=$#"
[root@root test02]# ./test01.sh 10 11
./test01.sh 10 11
10 11
10 11
参数总个数为=2
#$0 表示本身
#$1 表示第一个参数
4、声明变量类型
declare主要用来声明变量的类型
语法
declare [参数] [变量名称=设置值] 或declare -f
参数:
- + 取消变量所设的属性。
- - 用来指定变量的属性。
- -f 仅显示函数。
- **r ** 将变量设置为只读。
- **x ** 指定的变量会成为环境变量,可供shell以外的程序来使用。
- i [设置值]可以是数值,字符串或运算式。
案例
[root@root test02]# vim test01.sh
a=1
b=2
c=$a+$b
echo $c
[root@root test02]# test01.sh
1+2
[root@root test02]# vim test01.sh
a=1
b=2
declare -i c=$a+$b
echo $c
[root@root test02]# test01.sh
3