Shell之变量的基础知识

Posted yaowx

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Shell之变量的基础知识相关的知识,希望对你有一定的参考价值。

一、什么是变量

1、什么是变量

变量就是用一个固定的字符串(字符、字符+数字的组合等)替代更多、更复杂的内容,该内容可能还包含变量、路径、字符串等其它内容。

变量是暂时存储数据的地方及数据标记,所存储的数据是存放在内容空间中,通过正确地调用内存看空间中变量的名字九可以取出与变量相对应的数据。

注意变量的数据是存放在内容中,所以重启计算机,一般普通变量会丢失。

简单变量案例

[root@node1 ~]# name="ywx"
[root@node1 ~]# echo $name
ywx

变量的赋值方式:先写变量名(如上的name),紧接着是赋值符号"=",最后是变量的值(如上是ywx),赋值符号"="的左右两边无空格。变量的值一般要加""。

2、Shell变脸的特性

默认情况下,bash shell是不会区分变量类型的,其它变成语言如(c、c++、java等)在定义一个变量时需要先定义变量的类型,常见的变脸类型为整数、字符串、小数等。shell变量在定义时可以不用去指定,当然也可以使用declare显示定义变量的类型,一般情况下shell变量没有这个需求。

3、变量的类型

变量的类型分为环境变量(全局变量)和普通变量(局部变量)。

环境变量:也被称为全局变量,可以在创建它们的Shell及其派生出来的任意子Shell中使用,环境变量有可以分为自定义环境变量和bash内置的环境变量。

普通变量:也成为局部变量,只能用于在创建它们的shell函数或shell脚本中使用。普通变量一般由开发者在开发脚本程序时创建。

二、环境变量

1、什么是环境变量

       环境变量一般是指用export内置命令导出的变量,用于定义Shell的运行环境,保证Shell命令的正确执行。Shell通过环境变量来确定登录用户名、命令路径、终端类型、登录目录等,所有的环境变量都是系统全局变量,可用于所有子进程中,这包括编辑器、Shell脚本和各类应用。 ?

       环境变量可以在命令行中设置和创建,但用户退出命令行时这些变量值就会丢失,因此,如果希望永久保存环境变量,可在用户家目录下的.bash_profile或.bashrc(非用户登录模式特有,例如远程SSH)文件中,或者全局配置/etc/bashrc(非用户登录模式特有,例如远程SSH)或/etc/profile文件中定义。在将环境变量放入上述的文件中后,每次用户登录时这些变量都将被初始化。 按照系统规范,所有环境变量的名字均采用大写形式。在将环境变量应用于用户进程程序之前,都应该用export命令导出定义,例如:正确的环境变量定义方法为export YWX=1。 ?

      有一些环境变量,比如HOME、PATH、SHELL、UID、USER等,在用户登录之前就已经被/bin/login程序设置好了。通常环境变量被定义并保存在用户家目录下的.bash_profile文件或全局的配置文件/etc/profile中。

[root@node1 ~]# export
declare -x HISTCONTROL="ignoredups"
declare -x HISTSIZE="1000"
declare -x HOME="/root"
declare -x HOSTNAME="node1"
declare -x LANG="en_US.UTF-8"
declare -x LESSOPEN="||/usr/bin/lesspipe.sh %s"
declare -x LOGNAME="root"
declare -x LS_COLORS="rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36:"
declare -x MAIL="/var/spool/mail/root"
declare -x OLDPWD
declare -x PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin"
declare -x PWD="/root"
declare -x SHELL="/bin/bash"
declare -x SHLVL="1"
declare -x SSH_CLIENT="192.168.32.102 51611 22"
declare -x SSH_CONNECTION="192.168.32.102 51611 192.168.32.211 22"
declare -x SSH_TTY="/dev/pts/0"
declare -x TERM="linux"
declare -x USER="root"
declare -x XDG_RUNTIME_DIR="/run/user/0"
declare -x XDG_SESSION_ID="291"

2、查看变量的方式

在查看设置的变量时,有3个命令可以显示变量的值:set、env和declare(替代早期的typeset)。

set命令输出所有的变量,包括全局变量和局部变量。

env命令只显示全局变量。

declare命令输出所有的变量、函数、整数和已经导出的变量。

set-o命令显示bash Shell的所有参数配置信息。

[root@node1 ~]# env
XDG_SESSION_ID=291
HOSTNAME=node1
TERM=linux
SHELL=/bin/bash
HISTSIZE=1000
SSH_CLIENT=192.168.32.102 51611 22
SSH_TTY=/dev/pts/0
USER=root
LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36:
MAIL=/var/spool/mail/root
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
PWD=/root
LANG=en_US.UTF-8
HISTCONTROL=ignoredups
SHLVL=1
HOME=/root
LOGNAME=root
SSH_CONNECTION=192.168.32.102 51611 192.168.32.211 22
LESSOPEN=||/usr/bin/lesspipe.sh %s
XDG_RUNTIME_DIR=/run/user/0
_=/usr/bin/env
[root@node1 ~]# declare |head
BASH=/bin/bash
BASHOPTS=checkwinsize:cmdhist:expand_aliases:extglob:extquote:force_fignore:histappend:interactive_comments:login_shell:progcomp:promptvars:sourcepath
BASH_ALIASES=()
BASH_ARGC=()
BASH_ARGV=()
BASH_CMDS=()
BASH_COMPLETION_COMPAT_DIR=/etc/bash_completion.d
BASH_LINENO=()
BASH_SOURCE=()
BASH_VERSINFO=([0]="4" [1]="2" [2]="46" [3]="2" [4]="release" [5]="x86_64-redhat-linux-gnu")
......
[root@node1 ~]# set -o
allexport          off
braceexpand        on
emacs              on
errexit            off
errtrace           off
functrace          off
hashall            on
histexpand         on
history            on
ignoreeof          off
interactive-comments    on
keyword            off
monitor            on
noclobber          off
noexec             off
noglob             off
nolog              off
notify             off
nounset            off
onecmd             off
physical           off
pipefail           off
posix              off
privileged         off
verbose            off
vi                 off
xtrace             off

3、自定义的环境变量

3.1设置子定义的环境变量

1、export 变量名=value
2、变量名=value; export 变量名
3、declare -x 变量名=value

案例:

[root@node1 ~]# export KING=king
[root@node1 ~]# SEAL=seal;export SEAL
[root@node1 ~]# declare -x KAKA=kaka
[root@node1 ~]# env |grep KING
KING=king
[root@node1 ~]# env |grep SEAL
SEAL=seal
[root@node1 ~]# env |grep KAKA
KAKA=kaka

注意:该环境变量是在内存中,重启或退出当前shell变量将会丢失。

3.2永久性的环境变量

3.2.1用户的环境变量

[root@node1 ~]# ll /root/.bashrc
-rw-r--r--. 1 root root 176 Dec 29  2013 /root/.bashrc
[root@node1 ~]# ll /root/.bash_profile 
-rw-r--r--. 1 root root 176 Dec 29  2013 /root/.bash_profile
#用户的永久性环境变量是在当前用户的家目录中的.bashrc和.bash_profile文件中设置

案例

[root@node1 ~]# echo KAKA=kaka >> /root/.bashrc #或echo KAKA=kaka >> /root/.bash_profile
[root@node1 ~]# tail -1 /root/.bashrc 
KAKA=kaka
#重启或退出当前shell,
[root@node1 ~]# exit
logout

Connection closed by foreign host.

Disconnected from remote host(node1-32.211) at 19:20:41.

Type `help to learn how to use Xshell prompt.
[c:~]$ 

Connecting to 192.168.32.211:22...
Connection established.
To escape to local shell, press Ctrl+Alt+].

Last login: Sun Oct  4 03:20:55 2020 from 172.38.47.155
[root@node1 ~]# echo $KAKA
kaka
[root@node1 ~]# su - ywx
Last login: Wed Sep 30 02:09:44 CST 2020 on pts/1
[ywx@node1 ~]$ echo $KAKA

[ywx@node1 ~]$ 
#看到KAKA变脸在root用户下还在,在其它用户下则没有该变量

3.2.2全局变量

/etc/profile
/etc/bashrc                                   #<==推荐在此文件中优先设置
/etc/profile.d/
#若要在登录后初始化或显示加载内容,则把脚本文件放在/etc/profile.d/下即可(无须加执行权限)。

案例1、设置登录提示

方案一:

在/etc/motd中设置
ni hao shell

[root@node1 ~]# vim /etc/motd
ni hao shell 
[root@node1 ~]# cat /etc/motd
ni hao shell 

[root@node1 ~]# exit
logout

Connection closed by foreign host.

Disconnected from remote host(node1-32.211) at 19:27:28.

Type `help to learn how to use Xshell prompt.
[c:~]$ 

Connecting to 192.168.32.211:22...
Connection established.
To escape to local shell, press Ctrl+Alt+].

Last login: Sun Oct  4 03:26:02 2020 from 172.38.47.155
ni hao shell         #<===登录时显示了登录信息"ni hao shell"
[root@node1 ~]#

方案二:

在/etc/profile.d/下添加文件脚本,可以不设置x权限
[root@node1 ~]# sed -i 1d /etc/motd
[root@node1 ~]# cat /etc/motd
[root@node1 ~]# echo echo ni hao shell >> /etc/profile.d/hello_shell.sh
[root@node1 ~]# cat /etc/profile.d/hello_shell.sh
echo ni hao shell
[root@node1 ~]# exit
logout

Connection closed by foreign host.

Disconnected from remote host(node1-32.211) at 19:32:13.

Type `help to learn how to use Xshell prompt.
[c:~]$ 

Connecting to 192.168.32.211:22...
Connection established.
To escape to local shell, press Ctrl+Alt+].

Last login: Sun Oct  4 03:31:01 2020 from 172.38.47.155
ni hao shell
[root@node1 ~]# 
#换一个用户登录
[root@node1 ~]# su - ywx
Last login: Sun Oct  4 03:22:41 CST 2020 on pts/0
ni hao shell
[ywx@node1 ~]$ 
#可以看到是全局生效

案例三:

在写java脚本时,最好定义java的环境变量,防止java程序无法正常启动

export JAVA_HOME=/application/jdk
export CLASSPATH=$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib
export PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH:$HOME/bin

4、显示和取消环境变量

4.1.通过echo或printf命令打印环境变量

常见的环境变量

·$HOME:用户登录时进入的目录。
·$UID:当前用户的UID(用户标识),相当于id-u。
·$PWD:当前工作目录的绝对路径名。
·$SHELL:当前SHELL。
·$USER:当前用户。
………
[root@node1 ~]# echo $HOME
/root
[root@node1 ~]# echo $UID
0
[root@node1 ~]# echo $PWD
/root
[root@node1 ~]# echo $SHELL
/bin/bash
[root@node1 ~]# echo $USER
root
[root@node1 ~]# printf "$HOME
"
/root

4.2.用env或set显示默认的环境变量

用env(printenv)显示默认环境变量

[root@node1 ~]# KING=king
[root@node1 ~]# echo $KING
king
[root@node1 ~]# env |grep KING
[root@node1 ~]# env
XDG_SESSION_ID=305
HOSTNAME=node1
TERM=linux
SHELL=/bin/bash
HISTSIZE=1000
SSH_CLIENT=172.38.47.155 59082 22
SSH_TTY=/dev/pts/0
USER=root
LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36:
MAIL=/var/spool/mail/root
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
PWD=/root
LANG=en_US.UTF-8
HISTCONTROL=ignoredups
SHLVL=1
HOME=/root
LOGNAME=root
SSH_CONNECTION=172.38.47.155 59082 192.168.32.211 22
LESSOPEN=||/usr/bin/lesspipe.sh %s
XDG_RUNTIME_DIR=/run/user/0
_=/usr/bin/env

用set也可以显示环境变量(包括局部变量)

[root@node1 ~]# KING=king
[root@node1 ~]# echo $KING
king
[root@node1 ~]# set |grep KING
KING=king
#set包含了局部变量
[root@node1 ~]# set |head -20
BASH=/bin/bash
BASHOPTS=checkwinsize:cmdhist:expand_aliases:extglob:extquote:force_fignore:histappend:interactive_comments:login_shell:progcomp:promptvars:sourcepath
BASH_ALIASES=()
BASH_ARGC=()
BASH_ARGV=()
BASH_CMDS=()
BASH_COMPLETION_COMPAT_DIR=/etc/bash_completion.d
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
COLUMNS=188
COMP_WORDBREAKS=$ 	
"‘><=;|&(:
DIRSTACK=()
EUID=0
GROUPS=()
HISTCONTROL=ignoredups
HISTFILE=/root/.bash_history
HISTFILESIZE=1000
HISTSIZE=1000
......

4.3、用unset消除本地变量和环境变量

删除本地变量
[root@node1 ~]#KING=king
[root@node1 ~]# echo $KING
king
[root@node1 ~]# unset KING
[root@node1 ~]# echo $KING

[root@node1 ~]# 
删除环境变量
[root@node1 ~]# echo $USER
root
[root@node1 ~]# unset USER
[root@node1 ~]# echo $USER

[root@node1 ~]# 

5、环境变量的总结

1、变量名通常要大写。
2、变量可以在自身的Shell及子Shell中使用。
3、常用export来定义环境变量。
4、执行env默认可以显示所有的环境变量名称及对应的值。
5、输出时用“$变量名”,取消时用“unset变量名”。
6、书写crond定时任务时要注意,脚本要用到的环境变量最好先在所执行的Shell脚本中重新定义。
7、如果希望环境变量永久生效,则可以将其放在用户环境变量文件或全局环境变量文件里。

6、环境变量初始化与对应文件的生效顺序

       在登录Linux系统并启动一个bash shell时,默认情况下bash会在若干个文件中查找环境变量的设置。这些文件可统称为系统环境文件。bash检查的环境变量文件的情况取决于系统运行Shell的方式。系统运行Shell的方式一般有3种:

1)通过系统用户登录后默认运行的Shell。

2)非登录交互式运行Shell。

3)执行脚本运行非交互式Shell。

1、用户登录系统后首先会加载/etc/profile全局环境变量文件,这是Linux系统上默认的Shell主环境变量文件。系统上每个用户登录都会加载这个文件。
2、当加载完/etc/profile文件后,才会执行/etc/profile.d目录下的脚本文件,这个目录下的脚本文件有很多,例如:系统的字符集设置(/etc/sysconfig/i18n)等,在后文开发跳板机案例里,我们也把脚本的起始加载放到这个目录下,以便用户登录后即刻运行脚本。
3、之后开始运行$HOME/.bash_profile(用户环境变量文件),在这个文件中,又会去找$HOME/.bashrc(用户环境变量文件),如果有,则执行,如果没有,则不执行。在$HOME/.bashrc文件中又会去找/etc/bashrc(全局环境变量文件),如果有,则执行,如果没有,则不执行。
4、如果用户的Shell不是登录时启动的(比如手动敲下bash时启动或者其他不需要输入密码的登录及远程SSH连接情况),那么这种非登录Shell只会加载$HOME/.bashrc(用户环境变量文件),并会去找/etc/bashrc(全局环境变量文件)。因此如果希望在非登录Shell下也可读到设置的环境变量等内容,就需要将变量设定等写入$HOME/.bashrc或者/etc/bashrc,而不是$HOME/.bash_profile或/etc/profile。

三、普通变量

普通变量也叫本地变量是在用户当前Shell生存期的脚本中使用。例如,本地变量KING的取值为king,这个值只在用户当前Shell生存期中有意义。如果在Shell中启动另一个进程或退出,那么变量KING的值将会无效。

1、普通变量定义

变量名=value   #赋值不加引号
变量名=value   #赋值加单引号
变量名="value"   #赋值加双引号

2.在Shell中定义变量名及为变量内容赋值的要求

变量名一般是由字母、数字、下划线组成的,可以以字母或下划线开头,例如:ywx、ywx123、ywx_training、_kingseal2020。
变量的内容可以用单引号或双引号引起来,也可不加引号,但是这三者的含义是不同的。

赋值的内容
不带引号:赋值的内容中不能有空格
[root@node1 ~]# KING=king
[root@node1 ~]# echo $KING
king
[root@node1 ~]# KING=king kaka
-bash: kaka: command not found

带双引号:赋值的内容可以有空格,赋值的内容可以是变量
[root@node1 ~]# KING="king kaka"
[root@node1 ~]# echo $KING
king kaka
[root@node1 ~]# KAKA=kaka
[root@node1 ~]# KING="ni hao $KAKA"
[root@node1 ~]# echo $KING
ni hao kaka

带单引号:赋值的内容是什么就输出什么,如果有变量或特殊符号也原样输出
[root@node1 ~]# KAKA=kaka
[root@node1 ~]# KING="ni hao $KAKA"
[root@node1 ~]# echo $KING
ni hao kaka
[root@node1 ~]# KAKA=kaka
[root@node1 ~]# echo $KAKA
kaka
[root@node1 ~]# KING=ni hao $KAKA

[root@node1 ~]# echo $KING
ni hao $KAKA

#$KAKA没有引号其值kaka,"
"在echo表示换行,也只显示了"
",没有显示其转义的意思。

3、把一个命令的结果作为变量的内容赋值的方法

对需要获取命令结果的变量内容赋值的常见方法有两种:

变量名=`ls`        #<==把命令用反引号引起来,不推荐使用这种方法,因为容易和单引号混淆
变量名=$(ls)       #<==把命令用$()括起来,推荐使用这种方法

案例:

[root@node1 ~]# ls /data
test.log
[root@node1 ~]# CMD=`ls /data`
[root@node1 ~]# echo $CMD
test.log

[root@node1 ~]# CMD2=$(ls /data)
[root@node1 ~]# echo $CMD2
test.log

4、局部(普通)变量定义及赋值总结

常规普通变量定义:
1、若变量内容为连续的数字或字符串,赋值时,变量内容两边可以不加引号,例如a=1232、变量的内容很多时,如果有空格且希望解析内容中的变量,就加双引号,例如a="/etc/rc.local$USER",此时输出变量会对内容中的$USER进行解析然后再输出。
3、希望原样输出变量中的内容时就用单引号引起内容进行赋值,例如:a=$USER。
希望变量的内容是命令的解析结果的定义及赋值如下:
4、要使用反引号将赋值的命令括起来,例如:a=`ls`;或者用$()括起来,例如:a=$(ls)。

变量的输出方法如下:
1、使用“$变量名”即可输出变量的内容,常用“echo$变量名”的方式,也可用printf代替echo输出更复杂的格式内容。
变量定义的技巧及注意事项:
2、注意命令变量内容前后的字符``(此字符为键盘Tab键上面的那个反引号,不是单引号),例如:“CMD=`ls`”。
3、在变量名前加$可以取得该变量的值,使用echo或printf命令可以显示变量的值,$A和${A}的写法不同,但效果是一样的。
4、用echo等命令输出变量的时候,也可用单引号、双引号、反引号,例如:echo$A、echo"$A"echo$A,它们的用法和前面变量内容定义的总结是一致的。
5、$dbname,当变量后面连接有其他字符的时候,必须给变量加上大括号{},例如:$dbname_tname就要改成${dbname}_tname。

四、变量定义及变量输出说明(变量的引号说明)

单引号:
所见即所得,即输出时会将单引号内的所有内容都原样输出,或者为单引号内看到的是什么就输出什么,也称为强引用。

双引号:
输出双引号内的所有内容;如果内容有命令(要反引下或$())、变量、特殊转义符等,会先把变量、命令、转义字符解析出结果,然后再输出最终内容,也称为弱引用。

无引号:
赋值时,如果变量内容中有空格,则会造成赋值的不完整。而在输出内容时,会将含有空格的字符串视为一个整体来输出;如果内容中有命令(要反引下或$())、变量等,则会先把变量、命令解析出结果,然后输出最终内容;如果字符串中带有空格等特殊字符,则有可能无法完整地输出,因此需要改价双引号。一般连续的字符串、数字、路径等可以不加任何引号进行赋值和输出,建议使用双引号。

反引号(``):
一般用于命令,执行时命令会被执行,等价于$(),赋值和输出都要用``将命令引起来。

五、变量定义的规范

建议参考操作系统自带的/etc/init.d/functions函数库脚本的定义思路

(1)变量名及变量内容定义小结

 
1、变量名只能为字母、数字或下划线,只能以字母或下划线开头。
2、变量名的定义要有一定的规范,并且要见名知意
3、一般的变量定义、赋值常用双引号;简单连续的字符串可以不加引号;希望原样输出时使用单引号。
4、希望变量的内容是命令的解析结果时,要用反引号``,或者用$()把命令括起来再赋值。

(2)Shell定义变量时使用“=”的知识

"a=1"里等号是赋值的意思;比较变量是否相等时也可以用"="或"=="。

(3)打印输出及使用变量的知识

1、打印输出或使用变量时,变量名前要接$符号;变量名后面紧接其他字符的时候,要用大括号将变量部分单独括起来;在unset、export、(())等场景中使用但不打印变量时不加$,这个有些例外。
2、打印输出或使用变量时,一般加双引号或不加引号;如果是字符串变量,最好加双引号;希望原样输出时使用单引号。

 

以上是关于Shell之变量的基础知识的主要内容,如果未能解决你的问题,请参考以下文章

shell编程之变量

Linux基础之shell变量

Linux基础之shell变量

Shell之变量的基础知识

shell基础之管道符和变量

Acwing Linux基础课笔记shell语法