Re: curiosity: 'typeset -xr' vs. 'export -r'
On Mon, Dec 12, 2022, at 4:43 AM, L A Walsh wrote: > On 2022/12/11 20:47, Lawrence Velázquez wrote: >> This happens because "declare"/"typeset" creates local variables >> within functions. Using -g works around this... >> >> $ Export() { declare -gx "$@"; } >> $ Export -r foo=1 >> $ declare -p foo >> declare -rx foo="1" >> >> ...but now "Export" always creates global variables, rather than >> scoping as "declare" and your alias-based version does. On the >> other hand, "export" also creates global variables, so in a sense >> the workaround version is more consistent. >> >> $ f() { export "$@"; } >> $ f var=1 >> $ declare -p var >> declare -x var="1" >> > > I see, but you still can't use "-r" w/export Of course not. I only meant to demonstrate that "export" always creates global variables, so a function that utilizes "declare -gx" actually behaves more like "export" then your alias does. > though I think the -r flag would get dropped in any exported shell The environment does not propagate the readonly attribute, no. > though > in that case, one might expect an error if one uses "typeset -xr" > along the lines of "-r flag won't be exported". The readonly attribute is still applied to the original shell variable, so there's no reason to produce an error. > Side curious: If one uses -g, does it cause the var to be defined > in all intervening functions as well as the top(global) > and current scope? It defines a global variable, which is then visible to all functions. -- vq
Re: curiosity: 'typeset -xr' vs. 'export -r'
On Tue, Dec 13, 2022 at 03:07:16AM -0500, Lawrence Velázquez wrote: > Of course not. I only meant to demonstrate that "export" always > creates global variables, so a function that utilizes "declare -gx" > actually behaves more like "export" then your alias does. This is a little inaccurate. `export' doesn't always act on the *global* variable, but "declare -g" does. The differences are that: * `declare' (without -g), always acts on variables in the current dynamic scope, and will create a new variable in the current dynamic scope if no variable with the name it was looking for exists. * `export' and `readonly' act on the variable they can see, and set their "x"/"r" attribute; they will only create a new variable (in the global scope) if no variable with the name they were looking for exists in any dynamic scope. Just like simple "a=b" assignments. What `declare -xr' does in a function: fun () { declare -xr a=2 } Is equivalent to: fun () { declare a=2 && # create a new "a" variable in the current scope # and set its value to 2 export a&& # set its "x" attribute readonly a # set its "r" attribute # when this function returns, that variable will be deleted } So, as we already know, a function that runs that runs only `declare' commands (without -p, -f, or -g) is pretty much useless. Examples: bash-5.1$ # the `export' and `readonly' in "fun2" will act on the "a" bash-5.1$ # variable in the dynamic scope of the "fun1" function bash-5.1$ declare -p a bash: declare: a: not found bash-5.1$ fun1 () { local a=hi; fun2; declare -p a ;} bash-5.1$ fun2 () { export a; readonly a;} bash-5.1$ a=hello; declare -p a; fun1; declare -p a declare -- a="hello" declare -rx a="hi" declare -- a="hello" bash-5.1$ setexportreadonly () { export -- "$1" && readonly -- "$1" ;} bash-5.1$ x=hi bash-5.1$ declare -p x bash-5.1$ setexportreadonly x bash-5.1$ declare -p x declare -rx x="hi" bash-5.1$ # `declare -g' will bypass all the dynamic scopes, and will bash-5.1$ # act on the global variable. bash-5.1$ declare -p g bash: declare: g: not found bash-5.1$ fun1 () { local g=hi; fun2; declare -p g ;} bash-5.1$ fun2 () { declare -grx g=hey ;} bash-5.1$ g=hello; declare -p g; fun1; declare -p g declare -- g="hello" # "g" in the global scope before calling fun2 declare -- g="hi"# "g" in the dynamic scope of fun1 after calling fun2 declare -rx g="hey" # "g" in the global scope after calling fun2 bash-5.1$ # `export', `readonly', and assignments in functions create bash-5.1$ # a new global variable if there are no visible variables bash-5.1$ # with the given name. bash-5.1$ declare -p v{1..5} bash: declare: v1: not found bash: declare: v2: not found bash: declare: v3: not found bash: declare: v4: not found bash: declare: v5: not found bash: declare: v6: not found bash-5.1$ fun1 () { local v4; fun2 "$1" ;} bash-5.1$ fun2 () { local v5; fun3 "$1" ;} bash-5.1$ fun3 () { local v6; eval " $1" ;} bash-5.1$ fun1 'v1=x'; fun1 'export v2=y'; fun1 'readonly v3=z' bash-5.1$ fun1 'v4=x'; fun1 'export v5=y'; fun1 'readonly v6=z' bash-5.1$ declare -p v{1..5} declare -- v1="x" declare -x v2="y" declare -r v3="z" bash: declare: v4: not found bash: declare: v5: not found bash: declare: v6: not found emanuele6
bash crashes if TERM is unset and the Delete key is pressed twice
This happens since 88d69b4fa224d93ef1d26b80229668397bb6496b . If bash is started with the TERM variable unset or empty, it will segfault and crash if you press the Delete key twice (it only happens for the first prompt, and if you don't press anything before the two Delete key presses). I was able to reproduce this in the linux virtual console, urxvt, and xterm, both running tmux and not running tmux. Reproduce with either of these commands: * env -i /path/to/bash-devel/bash --norc --noprofile * TERM= /path/to/bash-devel/bash --norc --noprofile If it is not reproducible with your terminal emulator, try: * xterm -e env -i /path/to/bash-devel/bash --norc --noprofile * xterm -e env 'TERM=' /path/to/bash-devel/bash --norc --noprofile emanuele6
Nested expansion in heredoc fails
Configuration Information [Automatically generated, do not change]: Machine: x86_64 OS: linux-gnu Compiler: gcc Compilation CFLAGS: -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wall uname output: Linux lano-work 6.0.0-5-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.0.10-2 (2022-12-01) x86_64 GNU/Linux Machine Type: x86_64-pc-linux-gnu Bash Version: 5.2 Patch Level: 2 Release Status: release Description: Parameter expansion within heredocs fails. The code below works with other shells aswell as bash 5.1 Repeat-By: BUILDDIR=/builds/test cat << EOC Dir: ${BUILDDIR#$(pwd)/} EOC
Re: curiosity: 'typeset -xr' vs. 'export -r'
On Tue, Dec 13, 2022, at 6:38 AM, Emanuele Torre wrote: > On Tue, Dec 13, 2022 at 03:07:16AM -0500, Lawrence Velázquez wrote: >> Of course not. I only meant to demonstrate that "export" always >> creates global variables, so a function that utilizes "declare -gx" >> actually behaves more like "export" then your alias does. > > This is a little inaccurate. > > `export' doesn't always act on the *global* variable, but "declare -g" > does. > > The differences are that: > * `declare' (without -g), always acts on variables in the current >dynamic scope, and will create a new variable in the current dynamic >scope if no variable with the name it was looking for exists. > > * `export' and `readonly' act on the variable they can see, and set >their "x"/"r" attribute; they will only create a new variable (in the >global scope) if no variable with the name they were looking for >exists in any dynamic scope. Just like simple "a=b" assignments. You're right, thanks for clarifying. I was thinking exclusively about the behavior when creating variables. -- vq