1 | declare
|
2 | ===
|
3 |
|
4 | 声明变量,设置或显示变量的值和属性。
|
5 |
|
6 | ## 语法
|
7 |
|
8 | ```shell
|
9 | declare [-aAfFgilnrtux] [-p] [name[=value] ...]
|
10 | ```
|
11 |
|
12 | ## 主要用途
|
13 |
|
14 | - 显示包含指定属性的全部变量和值
|
15 | - 显示包含指定属性的一到多个变量和值
|
16 | - 显示一到多个变量的属性和值
|
17 | - 显示所有变量的属性和值并显示函数的定义
|
18 | - 显示所有变量的属性和值
|
19 | - 显示所有全局变量的属性和值
|
20 | - 显示全部函数名和函数定义
|
21 | - 只显示全部函数名
|
22 | - 显示一到多个函数名和函数定义
|
23 | - 只显示一到多个函数名
|
24 | - 声明全局变量(可选:赋值)
|
25 | - 声明变量(可选:赋值、属性)
|
26 | - 增加、删除变量的属性(可选:赋值)
|
27 |
|
28 | ## 选项
|
29 |
|
30 | ```shell
|
31 | -f 将操作或显示限制为函数名及函数定义。
|
32 | -F 只显示函数名(调试时附加行号和源文件)。
|
33 | -g 在shell函数中使用时创建全局变量;其他情况下忽略。
|
34 | -p 显示每个名称的属性和值。
|
35 |
|
36 | *设置属性的选项:
|
37 | -a 创建数组(如果支持)。
|
38 | -A 创建关联数组(如果支持)。
|
39 | -i 增加整型属性。
|
40 | +i 删除整型属性。
|
41 | -l 增加小写属性,变量的值将转换为小写。
|
42 | +l 删除小写属性。
|
43 | -n 增加引用属性(如果该选项存在)。
|
44 | +n 删除引用属性(如果该选项存在)。
|
45 | -r 增加只读属性。
|
46 | -t 增加追踪属性。
|
47 | +t 删除追踪属性。
|
48 | -u 增加大写属性,变量的值将转换为大写。
|
49 | +u 删除大写属性。
|
50 | -x 增加导出属性。
|
51 | +x 删除导出属性。
|
52 | ```
|
53 |
|
54 | ## 参数
|
55 |
|
56 | ```shell
|
57 | name(可选):变量名或函数名。
|
58 | value(可选):变量的值。
|
59 | ```
|
60 |
|
61 | ## 返回值
|
62 |
|
63 | declare 返回true除非你提供了非法选项或赋值错误。具体导致异常的情况请查看**讨论**章节的**关于异常情况**。
|
64 |
|
65 | ## 例子
|
66 |
|
67 | ```shell
|
68 | # 声明变量,当然也欢迎您在这个网站(感谢本项目发起人 @jaywcjlove)查询linux命令。
|
69 | declare reference_website='https://wangchujiang.com/linux-command/'
|
70 |
|
71 | # 显示所有包含整型属性的变量和值。
|
72 | declare -i
|
73 | # 定义变量b并赋值为3,具有整型属性。
|
74 | declare -i b=5
|
75 | # 显示属性,返回 declare -i b="5"。
|
76 | declare -p b
|
77 | # 删除整型属性。
|
78 | declare +i b
|
79 | # 显示属性,返回 declare -- b="5"。
|
80 | declare -p b
|
81 | # 根据变量属性强制转换值的英文大小写。
|
82 | declare -u uc_var='abc'
|
83 | declare -l lc_var='ABC'
|
84 | # 显示'ABC abc';
|
85 | echo "${uc_var} ${lc_var}"
|
86 | ```
|
87 |
|
88 | ```shell
|
89 | # 定义函数内的全局变量
|
90 | function test(){
|
91 | declare -g a=3
|
92 | # 或者
|
93 | local -g b=3
|
94 | # 或者
|
95 | c=3
|
96 | # 让我们查看它们的属性。
|
97 | declare -p a b c
|
98 | }
|
99 | # 执行函数。
|
100 | test
|
101 | # 返回结果。
|
102 | # declare -- a="3"
|
103 | # declare -- b="3"
|
104 | # declare -- c="3"
|
105 |
|
106 | # 定义函数外的全局变量
|
107 | declare a=3
|
108 | b=3
|
109 | declare –p a b
|
110 | # 返回结果如下。
|
111 | # declare -- a="3"
|
112 | # declare -- b="3"
|
113 |
|
114 | # 定义局部变量
|
115 | function test2(){
|
116 | local -i a=3
|
117 | declare -i b=3
|
118 | }
|
119 | test2
|
120 | # 没有该变量(已经被销毁了)
|
121 | echo "${a} ${b}"
|
122 | # 因此,我们日常脚本中最常见的类似于'a=3'实际上是声明并赋值了一个全局变量。
|
123 | # 在接下来的 **讨论** 环节会延伸讨论全局和局部变量问题。
|
124 | ```
|
125 |
|
126 | ```shell
|
127 | # 注意,不能使用 `+a` 或 `+A` 取消数组,也不能使用 `+r` 取消只读属性。
|
128 |
|
129 | # 定义只读数组,设置属性的同时定义赋值。
|
130 | declare -ar season=('Spring' 'Summer' 'Autumn' 'Winter')
|
131 | # 或者这样。
|
132 | season=('Spring' 'Summer' 'Autumn' 'Winter')
|
133 | declare -ar season
|
134 | # 显示所有数组。
|
135 | declare -a
|
136 | # 定义关联数组。
|
137 |
|
138 | declare -A fruits=(['apple']='red' ['banana']='yellow')
|
139 | # 显示所有关联数组。
|
140 | declare -A
|
141 | ```
|
142 |
|
143 | ```shell
|
144 | # 显示所有变量的属性和值并显示函数的定义,输出很长。
|
145 | declare
|
146 | # 显示所有变量的属性和值。
|
147 | declare -p
|
148 | # 显示所有全局变量的属性和值。
|
149 | declare -g
|
150 | ```
|
151 |
|
152 | ```shell
|
153 | # 显示全部函数名和函数定义。
|
154 | declare -f
|
155 | # 只显示全部函数名。
|
156 | declare -F
|
157 |
|
158 | # 定义两个函数。
|
159 | function func_a(){ echo $(date +"%F %T"); }
|
160 | function func_b(){ cd /; ls -lh --sort=time; }
|
161 | # 显示一到多个函数名和函数定义。
|
162 | declare -f func_a func_b
|
163 | # 只显示一到多个函数名,验证某个名称是否已经定义为函数时有用。
|
164 | declare -F func_a func_b
|
165 | # 最好不要让函数名和变量名相同。
|
166 | ```
|
167 |
|
168 |
|
169 | ## 讨论
|
170 |
|
171 | 1. 全局和局部变量
|
172 |
|
173 | 正如上面**例子**指出的情况,我们在日常编写程序的时候需要了解这些概念,在这里
|
174 | 做个简要地介绍,当然你也可以很方便的搜索到相关内容。
|
175 |
|
176 | - 全局变量:在整个脚本执行期间,只要没有被删除就**一直存在**。
|
177 | - 局部变量:在函数内定义,函数执行后就被删除。
|
178 |
|
179 | 建议函数内使用`local`命令,函数外使用`declare`命令。
|
180 |
|
181 | > *不要在脚本中定义过多的全局变量,那样可能会被其他函数调用造成意料之外的后果,并且也不方便检查出来。*
|
182 | >
|
183 | > *更不用说缺乏必要的注释了 —— ZhuangZhu-74*
|
184 |
|
185 | 相关资料:
|
186 |
|
187 | - [google提供的编码规范](https://github.com/google/styleguide)
|
188 | - [全局变量的讨论](https://unix.stackexchange.com/questions/381761/what-do-declare-name-and-declare-g-do)
|
189 |
|
190 | 2. 关于`declare` `typeset` `export` `local` `readonly`命令
|
191 |
|
192 | 为什么`declare`能做到的事,还需要定义其他这些命令呢?
|
193 |
|
194 | 因为这样语句含义会更加明确,例如:
|
195 | - 设置导出属性的变量时,`export var`和`declare -x var`。
|
196 | - 在函数内声明变量时,使用`local`。
|
197 | - 声明只读变量,使用`readonly`。
|
198 |
|
199 | `typeset`和`declare`命令一样。
|
200 |
|
201 | 3. 关于异常情况
|
202 |
|
203 | 有多种原因导致`declare`失败,关于这些情况可以参考[bash在线文档declare部分\(最新版\)](https://www.gnu.org/software/bash/manual/bash.html#index-declare),或执行 `info bash`
|
204 | 查看`declare`部分最后一大串`an attempt is`开头的句子。
|
205 |
|
206 | ### 注意
|
207 |
|
208 | 1. 该命令是bash内建命令,相关的帮助信息请查看`help`命令。
|
209 | 2. 导出属性的相关介绍请查看'export'命令。
|
210 | 3. 只读属性的相关介绍请查看'readonly'命令。
|
211 | 4. 引用属性的相关介绍请查看'unset'命令的例子部分。
|
212 |
|
213 |
|