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

Ale*_*tos 50 shell-script

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

local cword words=()
Run Code Online (Sandbox Code Playgroud)

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

local var=value
Run Code Online (Sandbox Code Playgroud)

Ark*_*zyk 129

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

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

首先,所有Bash无需键入显式路径即可运行的命令,例如./command可以分为两类:Bash shell builtinsexternal commands. Bash shell builtins随附安装Bash并且是它的一部分,而external commands不是Bash. 这很重要,因为Bash shell builtins它们被记录在里面,man bash并且它们的文档也可以用help命令调用,而external commands通常记录在它们自己的文件中manpages或采取一些-h, --help标志之王。要检查命令是 aBash shell builtin还是 an external command

$ type local
local is a shell builtin
Run Code Online (Sandbox Code Playgroud)

它将显示how command would be interpreted if used as a command name(从help type)。在这里我们可以看到这local是一个shell builtin. 让我们看另一个例子:

$ type vim
vim is /usr/bin/vim
Run Code Online (Sandbox Code Playgroud)

在这里我们可以看到,这vim不是一个,shell builtin而是一个位于/usr/bin/vim. 但是,有时相同的命令可以同时安装为 anexternal command和 a shell builtin。添加-atype列出所有可能性,例如:

$ type -a echo
echo is a shell builtin
echo is /usr/bin/echo
echo is /bin/echo
Run Code Online (Sandbox Code Playgroud)

在这里我们可以看到echo既是 ashell builtin又是 an external command。但是,如果您只是键入echo并按下Returnashell builtin将被调用,因为它首先出现在此列表中。请注意,所有这些版本echo不必相同。例如,在我的系统上/usr/bin/echo--help标志,而 abuiltin没有。

好的,现在当我们知道这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.
Run Code Online (Sandbox Code Playgroud)

注意第一行:name[=value][和之间的所有内容]都是可选的。这是世界上许多manpages文档形式中使用的通用约定*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.
Run Code Online (Sandbox Code Playgroud)

所以,归根结底,我希望您现在可以更轻松地理解不同命令的Linux工作方式。

  • 非常好的答案。我正在通读它,希望您能解决初学者如何仅从代码“var=()”中自己发现数组赋值是什么,但我想即使不知道它的名称,也很难弄清楚你在找什么。;) (9认同)
  • 我登录只是为了我可以对你的回答投赞成票:) (3认同)

jor*_*anm 37

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


Oth*_*eus 35

local简单地声明一个变量仅在当前定义的函数中具有作用域,因此主执行环境无法“看到”该值。您不能local在函数之外使用。例子

func() {
   nonlocal="Non local variable"
   local onlyhere="Local variable"
}
func
echo $nonlocal 
echo $onlyhere
Run Code Online (Sandbox Code Playgroud)

输出:非局部变量

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

  • 这个答案对于需要快速理解的人更有意义。 (3认同)

Ele*_*fee 7

应该注意的是,Bash 是动态作用域的,这意味着local它的行为与您对其他语言的期望不同。

观察:

#!/usr/bin/env bash

x=15

print1 () {
    echo "I am printing $x"
}

print2 () {
    local x=44
    print1
}

print1 # prints "I am printing 15"
print2 # prints "I am printing 44"
print1 # prints "I am printing 15"
Run Code Online (Sandbox Code Playgroud)

所以本质上这local并不意味着“局部变量”,它意味着“本地重新定义的全局变量”

  • 可怕功能的好例子 (3认同)