在bash脚本中,声明和普通变量有什么区别?


43

在bash脚本中:

我们通过命名来创建变量:

abc=ok

或者我们可以使用 declare

declare abc=ok

有什么不同?

为什么bash有这么多创建变量的方法?


6
在函数中使用时declare,与local命令一样,将NAMEs设为本地。该-g选项禁止这种行为。请参阅help declare
赛勒斯(Cyrus)2016年

2
declare使创建关联数组,整数和只读变量成为可能。而且,它扩展了其参数,因此类似declare $name=1的事情是可能的。
choroba

Answers:


34

来自help -m declare

名称

    declare -设置变量值和属性。

概要

    declare[ -aAfFgilnrtux] [ -p] [ name[ ] ...]=value

描述

    设置变量值和属性。

    声明变量并为其赋予属性。如果未提供名称,则显示所有变量的属性和值。

    选项:

      -f
        将动作或显示限制为函数名称和定义
      -F
        将显示限制为仅函数名称(调试时加上行号和源文件)
      -g
        在shell函数中使用时创建全局变量;否则忽略
      -p
        显示每个NAME的属性和值

    设置属性的选项:

      -a
        使NAMEs索引数组(如果支持)
      -A
        制作NAME关联数组(如果支持)
      -i
        使NAME具有“整数”属性
      -l
        将NAME转换为小写
      -n
        使NAME引用以其值命名的变量
      -r
        使NAME成为只读
      -t
        使NAME具有“ trace”属性
      -u
        在分配时将NAME转换为大写
      -x
        使名称导出

    使用“ +”代替“ -”会关闭给定的属性。

    let当为变量赋值时,具有integer属性的变量将执行算术评估(请参阅命令)。

    在函数中使用时declare,与local 命令一样,将NAMEs设为本地。' -g'选项禁止这种行为。

    退出状态:
    返回成功,除非提供了无效的选项或发生了变量分配错误。

也可以看看

    重击(1)

实施方式

    GNU bash,版本4.3.11(1)-发行版(i686-pc-linux-gnu)
    版权所有(C)2013 Free Software Foundation,Inc.
    许可证GPLv3 +:GNU GPL版本3或更高版本<http://gnu.org/ licenses / gpl.html>


因此,declare用于设置变量值和属性

让我通过一个非常简单的示例演示两个属性的用法:

$ # First Example:
$ declare -r abc=ok
$ echo $abc
ok
$ abc=not-ok
bash: abc: readonly variable


$ # Second Example:
$ declare -i x=10
$ echo $x
10
$ x=ok
$ echo $x
0
$ x=15
$ echo $x
15
$ x=15+5
$ echo $x
20

从上面的示例中,我认为您应该了解declare变量而不是普通变量的用法!这种类型的declare指令在函数,脚本循环中很有用。

另请访问键入变量:声明或排版


是的,“和属性”才是重点!这是区别。
lovespring

大!我喜欢例子,这是最好的教学/学习方式。谢谢!
turkenh

1
您需要知道什么是“属性”才能理解此答案。它们是变量的属性,例如“整数”,“数组”或“只读”。
本体

11

abc=ok给变量赋一个值abcdeclare abc声明一个名为的变量abc。两者可以组合为declare abc=ok

在bash中,像其他shell一样,不需要声明字符串和数组变量,因此declare除非您想传递选项(例如declare -A abc,使abc关联数组或declare -r使变量为只读),否则不需要声明。但是,在函数内部declare确实有所不同:它使变量在函数本地,这意味着保留函数外部的变量值(如果有)。(除非使用declare -g,否则会使变量不是局部的;与其他选项结合使用时,例如declare -gA在函数中创建全局关联数组时,这很有用。)示例:

f () {
  declare a
  a='a in f'
  b='b in f'
  echo "From f: a is $a"
  echo "From f: b is $b"
}
a='Initial a'
b='Initial b'
f
echo "After f: a is $a"
echo "After f: b is $b"

输出:

From f: a is a in f
From f: b is b in f
After f: a is Initial a
After f: b is b in f

declare内置函数可以做的另一件事是

declare内置是独一无二的庆典。它受到了强烈的启发,非常接近ksh的typeset内置函数,bash typeset作为declare兼容性的同义词提供。(我不知道为什么bash不只是称呼它typeset)。还有第三个同义词local。为了兼容性(与每个Bourne风格的shell export相同)declare -x,还有,与相同。


是!关键是“和选项”。ps:如果我设计bash,我将让“ declare”的行为在不同的情况下做一些事情。这使事情变得简单。
lovespring

好答案。进一步的问题,其中一个之中exportlocaldeclare与其他炮弹最兼容?
0xc0de

1
@ 0xc0de export存在于的所有变体中shlocal仅存在于bash和zsh中,declare仅存在于bash中。typeset存在于ksh,bash和zsh中。
吉尔斯(Gilles)“所以
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.