Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
Last revision Both sides next revision
commands:builtin:declare [2011/01/03 17:28]
thebonsai xlinks
commands:builtin:declare [2013/04/14 15:49]
ormaaj [Nameref] comments
Line 28: Line 28:
 |''​[-+]a'' ​ |make NAMEs indexed arrays (removing with ''​+a''​ is valid syntax, but leads to an error message) ​ | |''​[-+]a'' ​ |make NAMEs indexed arrays (removing with ''​+a''​ is valid syntax, but leads to an error message) ​ |
 |''​[-+]A'' ​ |make NAMEs associative arrays ​ | |''​[-+]A'' ​ |make NAMEs associative arrays ​ |
 +|''​[-+]c'' ​ | **Undocumented** convert NAMEs to "​capcase"​ on assignment (makes the first letter upper-case and the rest lower). Requires Bash built with ''​-DCASEMOD_CAPCASE'' ​ |
 |''​-f'' ​ |restrict action or display to function names and definitions (removing with ''​+f''​ is valid syntax, but leads to an error message) ​ | |''​-f'' ​ |restrict action or display to function names and definitions (removing with ''​+f''​ is valid syntax, but leads to an error message) ​ |
 |''​-F'' ​ |restrict display to function names only (plus line number and source file when debugging) ​ | |''​-F'' ​ |restrict display to function names only (plus line number and source file when debugging) ​ |
Line 33: Line 34:
 |''​[-+]i'' ​ |make NAMEs have the "​integer"​ attribute ​ | |''​[-+]i'' ​ |make NAMEs have the "​integer"​ attribute ​ |
 |''​[-+]l'' ​ |convert NAMEs to lower case on assignment (makes sure the variable contains only lower case letters) ​ | |''​[-+]l'' ​ |convert NAMEs to lower case on assignment (makes sure the variable contains only lower case letters) ​ |
 +|''​[-+]n'' ​ |make NAME a reference to the variable named by its value. Introduced in Bash 4.3-alpha ​ |
 |''​-p'' ​ |display the attributes and value of each NAME  | |''​-p'' ​ |display the attributes and value of each NAME  |
 |''​[-+]r'' ​ |make NAMEs readonly (removing with ''​+r''​ is valid syntax, but not possible) ​ | |''​[-+]r'' ​ |make NAMEs readonly (removing with ''​+r''​ is valid syntax, but not possible) ​ |
Line 39: Line 41:
 |''​[-+]x'' ​ |make NAMEs exported ​ | |''​[-+]x'' ​ |make NAMEs exported ​ |
  
-==== Errors ​====+==== Return status ​====
  
 ^Status ​ ^Reason ​ ^ ^Status ​ ^Reason ​ ^
Line 51: Line 53:
 |!= 0  |attempt to use ''​+a''​ to "​destroy"​ an array  | |!= 0  |attempt to use ''​+a''​ to "​destroy"​ an array  |
 |!= 0  |attemt to display a non-existent function with ''​-f'' ​ | |!= 0  |attemt to display a non-existent function with ''​-f'' ​ |
 +
 +===== Notes =====
 +
 +Unix shells offer very few datatypes. Bash and some other shells extend this by allowing "​attributes"​ to be set on variable names. The only attributes specified by POSIX are ''​export''​ and ''​readonly'',​ which are set by their own dedicated builtins. Datatypes in bash have a few other interesting capabilities such as the ability to modify data on assignment.
  
 ===== Examples ===== ===== Examples =====
Line 75: Line 81:
 } }
 </​code>​ </​code>​
 +
 +==== Nameref ====
 +
 +Bash 4.3 adds a new way to indirectly reference variables. ''​typeset -n''​ can be used to make a variable indirectly refer to another. In Bash, the lvalue of the assignment given to ''​typeset -n''​ will refer to the variable whose name is expanded on the RHS.
 +
 +<​code>​
 +# Sum a set of arrays and assign the result indirectly, also printing each intermediary result (without portability workarounds)
 +# sum name arrname [ arrname ... ]
 +function sum {
 +    typeset -n _result=$1 _arr
 +    typeset IFS=+
 +    _result=0
 +    for _arr in "​${@:​2}";​ do                        # Demonstrate the special property of "​for"​ on a nameref.
 +        (( _result += ${_arr[*]} ))
 +        printf '%s = %d\n' "​${!_result}"​ "​$_result"​ # Demonstrate the special property of ${!ref} on a nameref.
 +    done
 +}
 +
 +a=(1 2 3) b=(6 5 4) c=(2 4 6)
 +sum total a b c
 +printf 'Final value of "​total"​ is: %d\n' "​$total"​
 +</​code>​
 +
 +''​typeset -n''​ is currently implemented in ksh93, mksh, and Bash 4.3. Bash and mksh's implementations are quite similar, but much different from ksh93'​s. See [[#​portability_considerations | Portability considerations]] for details. ksh93 namerefs are much more powerful than Bash'​s.
  
 ===== Portability considerations ===== ===== Portability considerations =====
  
   * ''​declare''​ is not specified by POSIX(r)   * ''​declare''​ is not specified by POSIX(r)
-  * there is Bash synonym ''​typeset''​, which is marked ​as obsolete: Use ''​declare''​ +  * ''​declare'' ​is unique to Bash and totally non-portable with the possible exception of Zsh in Bash compatibility mode. Bash marks the synonym ''​typeset''​ as obsolete, which in Bash behaves identically to ''​declare''​. All other Korn-like shells use ''​typeset''​, so it probably isn't going away any time soon. Unfortunately,​ being a non-standard builtin, ''​typeset''​ differs significantly between shells. ksh93 also considers ''​typeset''​ a special ​builtin, while Bash does not - even in POSIX mode. If you use ''​typeset''​you should attempt to only use it in portable ways. 
-  * the Korn shell ''​typeset''​ special ​command is not fully compatiblebut some options are+  * **todo** nameref portability...
  
 ===== See also ===== ===== See also =====
Line 86: Line 116:
   * [[commands:​builtin:​readonly]]   * [[commands:​builtin:​readonly]]
   * [[commands:​builtin:​unset]]   * [[commands:​builtin:​unset]]
 +  * [[http://​austingroupbugs.net/​view.php?​id=351 | declaration commands]] will change the behavior of certain builtins such as ''​export''​ in the next version of POSIX.
  • commands/builtin/declare.txt
  • Last modified: 2013/04/14 20:11
  • by ormaaj