bash 中使用 local 关键字定义变量

bash 中使用 local 关键字定义变量

我正在学习 bash 脚本,并在我的 /usr/share/bash-completion 第 305 行找到了这个:

local cword words=()

它有什么作用?网上所有教程都只是格式

local var=value

答案1

虽然我喜欢乔丹给出的答案我认为向经验不足的 Linux 用户展示如何自己处理此类问题也同样重要。

与在 Google 搜索结果页面上显示的随机页面中寻找答案相比,建议的方法更快、更通用。

首先,所有可以在 Bash 中运行而无需键入显式路径的命令可以./command分为两类:Bash shell 内置函数外部命令。 Bash shell 内置命令随 Bash 一起安装并且是 Bash 的一部分,而外部命令不是 Bash 的一部分。这很重要,因为 Bash shell 内置命令记录在内部man bash,并且它们的文档也可以通过help命令调用,而外部命令通常记录在它们自己的手册页中或采用某种标志,例如-h, --help.要检查命令是 Bash shell 内置命令还是外部命令:

$ type local
local is a shell builtin

它将显示如果用作命令名称(来自help type),命令将如何解释。在这里我们可以看到这local是一个 shell 内置函数。让我们看另一个例子:

$ type vim
vim is /usr/bin/vim

在这里我们可以看到这vim不是 shell 内置命令,而是位于/usr/bin/vim.但是,有时相同的命令可以既作为外部命令安装,又同时作为 shell 内置命令安装。添加-atype列出所有可能性,例如:

$ type -a echo
echo is a shell builtin
echo is /usr/bin/echo
echo is /bin/echo

在这里我们可以看到它既echo是一个 shell 内置命令,也是一个外部命令。但是,如果您只是键入echo并按下,Return则会调用 shell 内置命令,因为它首先出现在此列表中。请注意,所有这些版本echo不需要相同。例如,在我的系统上/usr/bin/echo需要--help标记,而 Bash 内置系统则不需要。

好的,现在当我们知道这local是一个内置的 shell 时,让我们看看它是如何工作的:

$ help local
local: local [option] name[=value] ...
Define local variables.

Create a local variable called NAME, and give it VALUE.  OPTION can
be any option accepted by `declare'.

Local variables can only be used within a function; they are visible
only to the function where they are defined and its children.

Exit Status:
Returns success unless an invalid option is supplied, an error occurs,
or the shell is not executing a function.

注意第一行:name[=value][和之间的一切]都是选修的。这是世界上许多手册页和文档形式中使用的常见约定*nix。话虽如此,您在问题中询问的命令是完全合法的。反过来,...性格意味着前面的论点可以重复。您还可以在以下版本中阅读有关此约定的内容man man

The following conventions apply to the SYNOPSIS section and can be used
as a guide in other sections.

bold text          type exactly as shown.
italic text        replace with appropriate argument.
[-abc]             any or all arguments within [ ] are optional.
-a|-b              options delimited by | cannot be used together.
argument ...       argument is repeatable.
[expression] ...   entire expression within [ ] is repeatable.

所以,最终,我希望您现在能够更轻松地理解 Linux 中不同命令的工作原理。

答案2

你的例子

local cword words=()

在当前函数的范围内定义一个标量变量cword和一个空数组。words

local只是将变量声明为仅在当前定义的函数中具有作用域,以便主执行环境无法“看到”该值。您不能local在函数外部使用。例子

func() {
   nonlocal="Non local variable"
   local onlyhere="Local variable"
}
func
echo $nonlocal 
echo $onlyhere

输出:非局部变量

所以$onlyhere在函数范围之外是不可见的。

答案3

关键字local可以采用多个变量。为变量提供值是可选的。您的示例声明了两个变量,cwordwords。该words变量被分配了一个空数组。

答案4

问候 Unix & Linux SE / @alex-santos 的用户,这里是对这个问题的完整回答,一个全面的回应!

一只忙碌的猫


问题1

local cword words=()

它有什么作用?

答案1

local 关键字可以采用多个变量。为变量提供值是可选的。您的示例声明了两个变量:cword 和words。“(感谢@jordanm!)

SC2155 可能需要注意,您应该单独声明和分配。

话虽这么说,除了在参数之间使用多个声明选项之外,它仍然可以工作。另请注意,声明参数将应用于所有变量(在本例中为 -i)。看这里可以在一行中声明多个局部变量吗

words变量被分配了一个空数组。因为变量被设置为local访问级别,它必须在 shell 函数中声明。变量local将覆盖同名的全局变量而不会引发错误。局部变量只会在函数执行期间替换全局变量的值。全局变量的值将是在任何覆盖函数范围之外进行管理的值。

此外,仅在函数作用域内声明且尚未全局声明或导入的变量将看到下面几个现有答案中的代码,这些答案说明了这种情况,以及我添加的用于涵盖下面描述的其他情况的代码。

*为@electric-coffee、@Otheus 干杯,以说明下面第一个函数/局部范围示例的情况之一,并*

使用 shell 函数演示给定所有访问权限和作用域排列的本地/全局变量。

情况 1. 局部作用域无法访问全局作用域,因为它不存在。

exampleFunction() {
   nonlocal="Non local variable"
   local localToExampleFunctionOnly="Local variable"
}

# Prints "Non local variable".
echo $nonLocal

情况 2. 在函数作用域内用局部变量值覆盖全局作用域变量。

# Set the globally accessible variable value.
globalVariable="Globally accessible variable."

# Prints "Globally accessible variable." to the console from within
# the global context.
echo $globalVariable;

exampleFunction() {
   globalVariable="Locally accessible variable."
   # Prints "Locally accessible variable."
   echo $globalVariable;
}

# Call function, printing "Globally accessible variable." to the console from within
# the global context.
exampleFunction

# Prints "Globally accessible variable." to the console 
# from within the global runtime environment (the original value set to globally accessible scope).
echo $globalVariable 

情况 3. 函数作用域内引用的全局作用域变量在全局作用域发生更改,然后从第二个函数作用域内输出。

# Set the globally accessible variable value.
globalVariable="Globally accessible variable."

# Prints "Globally accessible variable." to the console from within
# the global context.
echo $globalVariable

exampleFunction() {
    # Prints "Globally accessible variable." to the console 
    # from within the function scope context.
   echo $globalVariable;
}

# Call function the first time
exampleFunction

# Prints "Globally accessible variable." to the console 
# from within the global runtime environment.
echo $globalVariable

# Update the globally accessible variable to a new value.
globalVariable="That's all the cases for scoping I can think of..."

# Prints "That's all the cases for scoping I can think of..." to the 
# console from within the global context.
echo $globalVariable; 

# Call function the last time, now that the value has been updated
# from global and local scope.
# Prints "That's all the cases for scoping I can think of..." 
# from the `exampleFunction`.

# Prints "That's all the cases for scoping I can think of..." to the 
# console from within the function scoped context, re-referencing 
# the updated global value and printing it to the terminal's output.
echo $globalVariable

尝试将函数作用域视为代码空间,在执行时可以修改或引用局部变量,而不会受到“外部”环境的任何副作用。

总而言之,words=()是此 shell 脚本中设置的第二个局部变量,并且由于语法原因,其类型为 Array words=()。该()部分初始化为一个空数组,在通过 声明后可访问该空数组$words。通过$words[$elementNumericIndex] and set during initialization likewords=("bob" "john" "steve") orWords[0]="bob"`访问和元素。

*这是在 bash 中使用的完整文档,nix shell 变量(设置、访问等)。

https://tldp.org/LDP/Bash-Beginners-Guide/html/sect_10_02.html


问题2

网上所有教程都只是格式

local var=value

答案2

您可能已经知道,这是更常用的单值->变量赋值,用于维护键到值的变量关系,从而提高代码可读性,减少冗余,并在重新使用引用值时提高性能重新声明(重复对值进行硬编码),促进最佳实践,并减少在从重复的硬编码版本与友好命名的变量(也是最现代的变量)读取/设置/声明值时由于“胖手指”而导致的错误IDE 甚至编辑器都支持插件,或者本身就能够在声明后自动完成变量(如果在范围内并且取决于在编写应用程序时光标的位置)。


抽象的

我结合了该线程中提供的一些精彩答案,以便完整而简洁地回答OP的问题。

我偶然发现了这一点,并意识到,在我看来,完全回答我们OP的答案的最正确、最简洁的方法分散在@jordanm、@electric-coffee、@arkadiusz-drabczyk(直接从本地终端手册中引导我们获得良好的响应输出)为了解决OP关于使用声明函数作用域变量的问题local

local cword words=()


local var=value

一些有用的链接:

相关内容