有什么作用
declare name
Run Code Online (Sandbox Code Playgroud)
不提供任何选项吗?它是否声明了字符串变量的名称?
有什么作用
declare -g
Run Code Online (Sandbox Code Playgroud)
不提供变量名怎么办?它是否显示具有全局属性的所有变量的值?
我declare
在 Bash 手册的描述中没有找到答案。
谢谢。
Sté*_*las 15
shell 中的变量处理和作用域,尤其是bash
可能非常晦涩和不直观(有时还有错误)。
ksh
有typeset
一个类似的功能。ksh
, zsh
,yash
有typeset
. bash
具有typeset
作为一个别名declare
用于与兼容ksh
,zsh
具有declare
作为一个别名typeset
为兼容bash
。大多数外壳都有export
,readonly
并且local
实现了部分typeset
功能。
一个为什么的原因bash
作者选择declare
了typeset
可能是因为typeset
没有只设置类型,它也声明一个变量:介绍它在给定的范围内,可能与类型,属性和/或值。
在 中bash
,变量可以是:
declare
)它们可以是不同的类型:
并有几个属性:
(尽管类型和属性之间的区别可能非常模糊)。
并非所有类型和属性的组合都受支持或有效。
现在,declare
在当前范围内声明变量。bash
,即使它实现了动态作用域,它也会特别对待最外层的作用域。它称之为全局作用域。
declare
在全局范围内和在函数中调用时(我不是在谈论由子外壳引入或与环境相关联的那种单独范围),它的行为非常不同。
当您declare var
在函数内部执行并提供未在同一范围内声明相同的变量时,它会声明一个新变量,该变量最初未设置,并且隐藏了本var
应存在于父范围中的潜在变量(调用方功能)。
这是通过某种堆栈实现的动态范围。当函数退出时,变量的状态、类型、属性和值与调用函数时一样被恢复(从堆栈中弹出)。
然而,在任何函数之外(在全局范围内),declare
确实声明了一个变量,但如果之前设置过,则不会将其初始化为未设置(与declare
在同一函数范围内第二次使用时相同)。如果指定了类型,则可以转换变量的值,尽管并非所有转换路径都被允许(仅标量到数组/散列),并且可以添加或删除属性。
In bash
,在函数内declare -g
作用于堆栈底部的变量,在最外层(“全局”)范围内。
declare -g
从被激发ksh93
的typeset -g
。但是ksh93
实现静态范围,其中全局范围不同并且与每个函数范围分开。对动态范围做同样的事情毫无意义。在具有typeset -g
( mksh
, zsh
, yash
) 的所有其他 shell 中,typeset -g
用于更改变量的某些属性而不实例化新的本地属性。
在 中bash
,人们通常出于同样的目的使用它,但是因为它影响最外层作用域的变量而不是当前变量,所以它并不总是有效。
例如:
integer() { typeset -gi "$1"; }
Run Code Online (Sandbox Code Playgroud)
为了使变量的整数工作mksh
/ yash
/ zsh
。它bash
仅适用于未被调用者声明为本地的变量:
$ bash -c 'f() { declare a; integer a; a=1+1; echo "$a"; }; integer() { typeset -gi "$1"; }; f'
1+1
$ bash -c 'f() { integer a; a=1+1; echo "$a"; }; integer() { typeset -gi "$1"; }; f'
2
Run Code Online (Sandbox Code Playgroud)
请注意,export var
既不是 也不typeset -x var
是typeset -gx var
。export
如果变量已经存在,它会在不声明新变量的情况下添加属性。readonly
vs相同typeset -r
。
还要注意,unset
在bash
只有清除一个变量,如果它已经在当前范围内声明(叶子它宣称,虽然除了在全球范围内,它会删除属性和值和变量不再是数组或散列;还要注意,在namerefs,它取消设置引用的变量)。否则,它只是从上面提到的堆栈中弹出一个可变层。对于bash
5.0 或更高版本,可以通过设置localvar_unset
选项来修复。
所以总结一下:
declare var
Run Code Online (Sandbox Code Playgroud)
当在函数中调用并且如果var
之前未在同一函数中声明时,声明一个没有属性的标量类型的变量,并且最初未设置。
如果在任何函数之外调用或者如果var
已经在同一个函数中声明,则没有任何效果,因为我们没有指定任何新类型或属性。
declare -g var
Run Code Online (Sandbox Code Playgroud)
无论它在哪里被调用,都会var
在最外层(“全局”)范围内声明 a :使其声明为scalar类型,没有属性,如果它以前在该范围内未知,则没有值(对于所有意图和目的来说,这与一个未知变量,除非它会显示在 ) 的输出中typeset -p
,否则什么都不做。
无论如何,您可能无法在运行该命令的上下文中访问该变量:
f() { local a; g; }; g() { typeset -g a=123; echo "$a"; }; f
Run Code Online (Sandbox Code Playgroud)
什么都不输出。
declare name
Run Code Online (Sandbox Code Playgroud)
来自https://www.gnu.org/software/bash/manual/bashref.html#Bash-Builtins
声明变量并赋予它们属性。
您尚未提供任何选项,因此未分配任何属性,并且name
已创建变量。未提供任何值,因此未分配任何值。
declare -g
Run Code Online (Sandbox Code Playgroud)
-g 选项强制在全局范围内创建或修改变量,即使在 shell 函数中执行 statements 时也是如此。在所有其他情况下都会忽略它。
由于您没有提供 a name
,因此不会创建任何变量,因此它会被忽略。你自己看:
declare -g > foo
declare > bar
diff foo bar
Run Code Online (Sandbox Code Playgroud)
唯一的区别可能是 Bash 变量的值$_
,并且可能PIPESTATUS
基于您之前的命令;返回的变量列表没有其他区别。
归档时间: |
|
查看次数: |
5330 次 |
最近记录: |