github.com/lmorg/murex@v0.0.0-20240217211045-e081c89cd4ef/docs/commands/export.md (about) 1 # `export` 2 3 > Define an environmental variable and set it's value 4 5 ## Description 6 7 Defines, updates or deallocates an environmental variable. 8 9 ## Usage 10 11 ``` 12 <stdin> -> export var_name 13 14 export var_name=data 15 ``` 16 17 ## Examples 18 19 As a method: 20 21 ``` 22 » out "Hello, world!" -> export hw 23 » out "$hw" 24 Hello, World! 25 ``` 26 27 As a function: 28 29 ``` 30 » export hw="Hello, world!" 31 » out "$hw" 32 Hello, World! 33 ``` 34 35 ## Detail 36 37 ### Deallocation 38 39 You can unset variable names with the bang prefix: 40 41 ``` 42 !export var_name 43 ``` 44 45 For compatibility with other shells, `unset` is also supported but it's really 46 not an idiomatic method of deallocation since it's name is misleading and 47 suggests it is a deallocator for local Murex variables defined via `set`. 48 49 ### Exporting a local or global variable 50 51 You can also export a local or global variable of the same name by specifying 52 that variable name without a following value. For example 53 54 ``` 55 # Create a local variable called 'foo': 56 » set foo=bar 57 » env -> grep: foo 58 59 # Export that local variable as an environmental variable: 60 » export: foo 61 » env -> grep: foo 62 foo=bar 63 64 # Changing the value of the local variable doesn't alter the value of the environmental variable: 65 » set foo=rab 66 » env -> grep: foo 67 foo=bar 68 » out $foo 69 rab 70 ``` 71 72 ### Type Annotations 73 74 When `set` or `global` are used as a function, the parameters are passed as a 75 string which means the variables are defined as a `str`. If you wish to define 76 them as an alternate data type then you should add type annotations: 77 78 ``` 79 » set int age = 30 80 ``` 81 82 (`$age` is an integer, `int`) 83 84 ``` 85 » global bool dark_theme = true 86 ``` 87 88 (`$dark_theme` is a boolean, `bool`) 89 90 When using `set` or `global` as a method, by default they will define the 91 variable as the data type of the pipe: 92 93 ``` 94 » open example.json -> set: file 95 ``` 96 97 (`$file` is defined a `json` type because `open` wrote to `set`'s pipe with a 98 `json` type) 99 100 You can also annotate `set` and `global` when used as a method too: 101 102 ``` 103 out 30 -> set: int age 104 ``` 105 106 (`$age` is an integer, `int`, despite `out` writing a string, `str, to the pipe) 107 108 > `export` does not support type annotations because environmental variables 109 > must always be strings. This is a limitation of the current operating systems. 110 111 ### Scoping 112 113 Variable scoping is simplified to three layers: 114 115 1. Local variables (`set`, `!set`, `let`) 116 2. Global variables (`global`, `!global`) 117 3. Environmental variables (`export`, `!export`, `unset`) 118 119 Variables are looked up in that order of too. For example a the following 120 code where `set` overrides both the global and environmental variable: 121 122 ``` 123 » set foobar=1 124 » global foobar=2 125 » export foobar=3 126 » out $foobar 127 1 128 ``` 129 130 #### Local variables 131 132 These are defined via `set` and `let`. They're variables that are persistent 133 across any blocks within a function. Functions will typically be blocks 134 encapsulated like so: 135 136 ``` 137 function example { 138 # variables scoped inside here 139 } 140 ``` 141 142 ...or... 143 144 ``` 145 private example { 146 # variables scoped inside here 147 } 148 149 ``` 150 151 ...however dynamic autocompletes, events, unit tests and any blocks defined in 152 `config` will also be triggered as functions. 153 154 Code running inside any control flow or error handing structures will be 155 treated as part of the same part of the same scope as the parent function: 156 157 ``` 158 » function example { 159 » try { 160 » # set 'foobar' inside a `try` block 161 » set foobar=example 162 » } 163 » # 'foobar' exists outside of `try` because it is scoped to `function` 164 » out $foobar 165 » } 166 example 167 ``` 168 169 Where this behavior might catch you out is with iteration blocks which create 170 variables, eg `for`, `foreach` and `formap`. Any variables created inside them 171 are still shared with any code outside of those structures but still inside the 172 function block. 173 174 Any local variables are only available to that function. If a variable is 175 defined in a parent function that goes on to call child functions, then those 176 local variables are not inherited but the child functions: 177 178 ``` 179 » function parent { 180 » # set a local variable 181 » set foobar=example 182 » child 183 » } 184 » 185 » function child { 186 » # returns the `global` value, "not set", because the local `set` isn't inherited 187 » out $foobar 188 » } 189 » 190 » global $foobar="not set" 191 » parent 192 not set 193 ``` 194 195 It's also worth remembering that any variable defined using `set` in the shells 196 FID (ie in the interactive shell) is localised to structures running in the 197 interactive, REPL, shell and are not inherited by any called functions. 198 199 #### Global variables 200 201 Where `global` differs from `set` is that the variables defined with `global` 202 will be scoped at the global shell level (please note this is not the same as 203 environmental variables!) so will cascade down through all scoped code-blocks 204 including those running in other threads. 205 206 #### Environmental variables 207 208 Exported variables (defined via `export`) are system environmental variables. 209 Inside Murex environmental variables behave much like `global` variables 210 however their real purpose is passing data to external processes. For example 211 `env` is an external process on Linux (eg `/usr/bin/env` on ArchLinux): 212 213 ``` 214 » export foo=bar 215 » env -> grep foo 216 foo=bar 217 ``` 218 219 ### Function Names 220 221 As a security feature function names cannot include variables. This is done to 222 reduce the risk of code executing by mistake due to executables being hidden 223 behind variable names. 224 225 Instead Murex will assume you want the output of the variable printed: 226 227 ``` 228 » out "Hello, world!" -> set hw 229 » $hw 230 Hello, world! 231 ``` 232 233 On the rare occasions you want to force variables to be expanded inside a 234 function name, then call that function via `exec`: 235 236 ``` 237 » set cmd=grep 238 » ls -> exec $cmd main.go 239 main.go 240 ``` 241 242 This only works for external executables. There is currently no way to call 243 aliases, functions nor builtins from a variable and even the above `exec` trick 244 is considered bad form because it reduces the readability of your shell scripts. 245 246 ### Usage Inside Quotation Marks 247 248 Like with Bash, Perl and PHP: Murex will expand the variable when it is used 249 inside a double quotes but will escape the variable name when used inside single 250 quotes: 251 252 ``` 253 » out "$foo" 254 bar 255 256 » out '$foo' 257 $foo 258 259 » out %($foo) 260 bar 261 ``` 262 263 ## Synonyms 264 265 * `export` 266 * `!export` 267 * `unset` 268 269 270 ## See Also 271 272 * [Reserved Variables](../user-guide/reserved-vars.md): 273 Special variables reserved by Murex 274 * [Variable and Config Scoping](../user-guide/scoping.md): 275 How scoping works within Murex 276 * [`%(Brace Quote)`](../parser/brace-quote.md): 277 Initiates or terminates a string (variables expanded) 278 * [`??` Null Coalescing Operator](../parser/null-coalescing.md): 279 Returns the right operand if the left operand is empty / undefined (expression) 280 * [`expr`](../commands/expr.md): 281 Expressions: mathematical, string comparisons, logical operators 282 * [`global`](../commands/global.md): 283 Define a global variable and set it's value 284 * [`is-null`](../commands/is-null.md): 285 Checks if a variable is null or undefined 286 * [`set`](../commands/set.md): 287 Define a local variable and set it's value 288 289 <hr/> 290 291 This document was generated from [builtins/core/typemgmt/variables_doc.yaml](https://github.com/lmorg/murex/blob/master/builtins/core/typemgmt/variables_doc.yaml).