0 前言
在
Linux shell编程学习笔记16:bash中的关联数组
中,我们在定义关联数组时使用了declare命令。
其实,declare命令的功能不只是定义定义关联数组,现在我们就来探讨它的功能和用法。
1 declare 命令的功能和格式
我们可以使用 命令 help declare 查看 的功能和格式
purpleEndurer @ bash $ help declare 
 declare: declare [-aAfFgilrtux] [-p] [name[=value] ...]
     Set variable values and attributes.
     
     Declare variables and give them attributes.  If no NAMEs are given,
     display the attributes and values of all variables.
     
     Options:
       -f        restrict action or display to function names and definitions
       -F        restrict display to function names only (plus line number and
         source file when debugging)
       -g        create global variables when used in a shell function; otherwise
         ignored
       -p        display the attributes and value of each NAME
     
     Options which set attributes:
       -a        to make NAMEs indexed arrays (if supported)
       -A        to make NAMEs associative arrays (if supported)
       -i        to make NAMEs have the `integer' attribute
       -l        to convert NAMEs to lower case on assignment
       -r        to make NAMEs readonly
       -t        to make NAMEs have the `trace' attribute
       -u        to convert NAMEs to upper case on assignment
       -x        to make NAMEs export
     
     Using `+' instead of `-' turns off the given attribute.
     
     Variables with the integer attribute have arithmetic evaluation (see
     the `let' command) performed when the variable is assigned a value.
     
     When used in a function, `declare' makes NAMEs local, as with the `local'
     command.  The `-g' option suppresses this behavior.
     
     Exit Status:
     Returns success unless an invalid option is supplied or an error occurs.

1.1 功能
declare命令的功能是 查看 或 设置变量值和属性;查看自定义函数的名称和定义。
     
1.2 格式
declare [-aAfFgilrtux] [-p] [变量名[=值] ...]
选项说明:
| 选项 | 功能描述 | 备注 | 
| -a | 使 指定变量名 成为索引数组(如果支持) | 属性选项,indexed arrays | 
| -A | 使 指定变量名 成为关联数组(如果支持) | 属性选项,ssociative arrays | 
| -f | 将操作或显示限制为函数名称和定义 | function | 
| -F | 将显示限制为仅函数名称(加上行号和调试时的源文件) | function | 
| -g | 在 shell 函数中使用时创建全局变量;否则忽视 | global | 
| -i | 使 指定变量名 具有“整数”属性 | 属性选项,integer | 
| -l | 在赋值时将 指定变量名 转换为小写 | 属性选项,lower case | 
| -p | 显示每个 指定变量名 的属性和值 | display | 
| -r  | 使 指定变量名 只读 | 属性选项,readonly | 
| -t | 使 指定变量名 具有“trace”属性 | 属性选项,trace | 
| -u | 在赋值时将 指定变量名转换为大写 | 属性选项,upper case | 
| -x | 使 指定变量名导出 | 属性选项,export | 
对于属性选项,"-"可用来指定变量的属性,"+"则是取消变量所设的属性。
- 注意:如果同时对多个变量进行操作,变量名之间用空格分隔
2 用法和实例
2.1 declare : 显示用户的shell变量 (局部变量和环境变量)和自定义函数
purpleEndurer @ bash $ declare | more
 BASH=/usr/bin/bash
 BASHOPTS=checkwinsize:cmdhist:expand_aliases:extquote:force_fignore:histappend:hostcomplete:interactive_comments: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'
 COLUMNS=144
 DIRSTACK=()
 EUID=1000
 GROUPS=()
 HISTFILE=/home/csdn/.bash_history
 HISTFILESIZE=500
 HISTSIZE=500
 HOME=/home/csdn
 HOSTNAME=edu
 HOSTTYPE=x86_64
 IFS=$' \t\n'
 LC_ALL=zh_CN.UTF-8
 LESS=-R
 LINES=32
 LOGNAME=csdn
 LSCOLORS=Gxfxcxdxbxegedabagacad
 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;3
 1:*.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=0
 1;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=0
 --More--

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;3
 1:*.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=0
 1;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=0
 1;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:'
 MACHTYPE=x86_64-redhat-linux-gnu
 MAILCHECK=60
 OPTERR=1
 OPTIND=1
 OSTYPE=linux-gnu
 PAGER=less
 PATH=/home/csdn/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
 PIPESTATUS=([0]="0")
 PPID=50
 PROMPT_COMMAND='printf "\033]0;%s@%s:%s\007" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/~}"'
 PS1='purpleEndurer @ bash $ '
 PS2='> '
 PS4='+ '
 PWD=/home/csdn
 SHELL=/bin/bash
 SHELLOPTS=braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor
 SHLVL=2
 TERM=xterm
 UID=1000
 ZSH=/home/csdn/.oh-my-zsh
 _=declare
 colors=/home/csdn/.dircolors
 purpleEndurer @ bash $  

由于当前用户没有自定义函数,所以目前只能看到变量的信息。
2.2 declare -i 变量名1[=值1] ……:声明整数型变量
例:声明整数型变量a和b,并初始化其值分别为1和2,然后显示a和b的值,再显示a与b的和
purpleEndurer @ bash $ declare -i a=1 b=2
 purpleEndurer @ bash $ echo $a,$b
 1,2
 purpleEndurer @ bash $ echo $[ a + b ]
 3

2.3 declare +属性 变量名:取消变量属性
例:声明整数型变量a和b,并初始化其值分别为1和2,然后给a赋值'a'。
purpleEndurer @ bash $ declare -i a=1 b=1 #声明整数型变量a和b,并初始化其值分别为1和2
 purpleEndurer @ bash $ a='a' b='b'   #给变量a赋值'a',变量b赋值'b'
 purpleEndurer @ bash $ echo $a $b #显示a和b的值
 1 1
 purpleEndurer @ bash $ declare +i a #取消变量a的整数属性
 purpleEndurer @ bash $ a='a' b='b'
 purpleEndurer @ bash $ echo $a $b #显示a和b的值
 a 1
 purpleEndurer @ bash $ 

可以看到,在 声明整数型变量a和b,并初始化其值分别为1和2后,直接给整型变量a和b赋字符串值是无效的。
需要取消变量a的整数属性后,才能给变量a赋字符串值'a'。
2.4 declare -r 变量名[=值]……:定义只读变量
定义只读整数变量c并初始化值为1
purpleEndurer @ bash ~ $ declare -ri c=1
 purpleEndurer @ bash ~ $ echo $c
 1
 purpleEndurer @ bash ~ $ c=2
 bash: c: readonly variable
 purpleEndurer @ bash ~ $ declare +r c
 bash: declare: c: readonly variable

只读变量的值无法更改。
无法用declare +r 来去除变量c的只读属性。
2.5 [declare -a ]索引数组名[=(值1 值2 ……) ]:定义索引数组
例:定义索引数组a并初始化,然后显示其值:
purpleEndurer @ bash ~ $ declare -a a=(1 'a' b)
 purpleEndurer @ bash ~ $ echo ${a[*]}
 1 a b

关于索引数组的更多知识,可以回顾:
Linux shell编程学习笔记15:定义数组、获取数组元素值和长度、数组拼接或合并
2.6 declare -A 关联数组名[=([字符串下标1]=值1 [字符串下标2]=值2 …… [字符串下标n]=值n)]:定义关联数组
例:定义关联数组b并初始化,然后显示其值:
purpleEndurer @ bash ~ $ declare -A b=(["apple"]=1 ["boy"]=2 ["cat"]=3)
 purpleEndurer @ bash ~ $ echo ${b[*]}
 3 1 2

关于关联数组的更多知识,可以回顾:
Linux shell编程学习笔记16:bash中的关联数组
2.7 declare -f[ 函数名]:显示指定的用户自定义函数名称和定义
例:定义函数a和b,然后用 declare -f命令查看它们的名称和定义代码
purpleEndurer @ bash ~ $ function a(){ echo $0;}
 purpleEndurer @ bash ~ $ a
 bash
 purpleEndurer @ bash ~ $ function b(){ echo $#;}
 purpleEndurer @ bash ~ $ b
 0
 purpleEndurer @ bash ~ $ declare -f
 a () 
 { 
     echo $0
 }
 b () 
 { 
     echo $#
 }
 purpleEndurer @ bash ~ $ declare -f a
 a () 
 { 
     echo $0
 }
 purpleEndurer @ bash ~ $ declare -f b
 b () 
 { 
     echo $#
 }
 purpleEndurer @ bash ~ $ 
 

如果在使用declare -f 命令时没有指定函数名,将显示所有的函数名和定义代码。
2.8 declare -F[ 函数名]:显示指定的用户自定义函数名称
例:我们用 declare -F命令查看2.7中例子自定义函数a和b的名称
purpleEndurer @ bash ~ $ declare -F
 declare -f a
 declare -f b
 purpleEndurer @ bash ~ $ declare -F a
 a
 purpleEndurer @ bash ~ $ declare -F b
 b
 purpleEndurer @ bash ~ $ 

与 declare -f 命令相似,如果在使用declare -F 命令时没有指定函数名,将显示所有的函数名。
3 declare命令与set命令在显示shell变量功能上的对比
set :显示用户的局部变量和用户环境变量。
declare: 跟set一样,显示用户的shell变量 (局部变量和环境变量)










