2017-07-31 41 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