2017-07-31 48 views
2

我喜欢用函数来组织我的代码,因为我使用的函数我也喜欢使用local变量。尽可能多地使用read-only变量,所以如果我在代码中犯了任何错误,它很容易被注意到。Bash本地和只读变量

但我一直在使用它很长一段时间错了。所以我决定写它来分享我的经验。

如何定义localread-only里面的bash函数? (请参阅下面的答案和解释)。

回答

2

第一次尝试:local readonly var1

这是我用来定义它的方式。这是错误的。我将把我的变量var1定义为local,但它不会是readonly,正如你可以在下面的例子中看到的,我可以改变var1的值,而我不想这么做!

:~$ (
>  myfunction() 
>  { 
>   # Define variable 
>   local readonly var1="val1" 
>   
>   echo "Readonly output:" 
>   readonly | grep -E 'readonly|local|var1' 
>   echo "" 
> 
>   echo "Local output:" 
>   local | grep -E 'readonly|local|var1' 
>   echo "" 
> 
>   var1="val2" 
>   echo "VAR1 INSIDE: ${var1}" 
>  } 
>  myfunction 
>  echo "VAR1 OUTSIDE: ${var1}" 
>) 
Readonly output: 

Local output: 
var1=val1 

VAR1 INSIDE: val2 
VAR1 OUTSIDE: 

第二次尝试:readonly local var1

这一次将定义var1readonly,但它也将定义一个名为local变量,因此采用这种方式,它不会处理local作为关键字,它会是一个变量名称。

检查一下,var1的范围不是local,实际上它是global,我们可以看到var1以外的值的函数。

:~$ (
>  myfunction() 
>  { 
>   # Define variable 
>   readonly local var1="val1" 
>   
>   echo "Readonly output:" 
>   readonly | grep -E 'readonly|local|var1' 
>   echo "" 
> 
>   echo "Local output:" 
>   local | grep -E 'readonly|local|var1' 
>   echo "" 
> 
>   echo "VAR1 INSIDE: ${var1}" 
>  } 
>  myfunction 
>  echo "VAR1 OUTSIDE: ${var1}" 
>) 
Readonly output: 
declare -r local 
declare -r var1="val1" 

Local output: 

VAR1 INSIDE: val1 
VAR1 OUTSIDE: val1 

因为它应该是:local -r var1

这样,它会做正是我想要的,我会定义为var1范围localreadonly

:~$ (
>  myfunction() 
>  { 
>   # Define variable 
>   local -r var1="val1" 
>   
>   echo "Readonly output:" 
>   readonly | grep -E 'readonly|local|var1' 
>   echo "" 
> 
>   echo "Local output:" 
>   local | grep -E 'readonly|local|var1' 
>   echo "" 
> 
>   #var1="val2" 
>   echo "VAR1 INSIDE: ${var1}" 
>  } 
>  myfunction 
>  echo "VAR1 OUTSIDE: ${var1}" 
>) 
Readonly output: 
declare -r var1="val1" 

Local output: 
var1=val1 

VAR1 INSIDE: val1 
VAR1 OUTSIDE: 

我们可以把它定义为如下,但是一行它比两行更好!

local var1="val1" 
readonly var1 
1

bash手册页中概括的事情正是如此为declare命令:

-r Make names readonly. These names cannot then be assigned values 
     by subsequent assignment statements or unset. 

When used in a function, declare and typeset make each name local, as with 
    the local command, unless the -g option is supplied. 

所以,如果你declare在函数中,你声明的变量将是本地默认。如果您使用-r选项,它将是只读的。

$ cat testv 
#!/usr/bin/env bash 

test1() { 
    declare -r var="$1" 
    var="bacon" 
} 

s=foo 
test1 bar 
echo "$s - $var" 

$ bash testv 
testv: line 5: var: readonly variable 
foo - 
+0

函数内的'declare -r'和'local -r'有什么区别? – Azize

+0

其中一个使用比另一个少两个字节将命令存储在脚本中。哦,另一个以“d”开头。 :) – ghoti