sourcing script file from inside a function doesn't work anymore
Configuration Information [Automatically generated, do not change]: Machine: x86_64 OS: linux-gnu Compiler: gcc Compilation CFLAGS: -DPROGRAM='bash' -DCONF_HOSTTYPE='x86_64' -DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='x86_64-pc-linux-gnu' -DCONF_VENDOR='pc' -DLOCALEDIR='/usr/share/locale' -DPACKAGE='bash' -DSHELL -DHAVE_CONFIG_H -I. -I../. -I.././include -I.././lib -D_FORTIFY_SOURCE=2 -g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -Wall uname output: Linux thioroup8-laptop 3.13.0-26-generic #48-Ubuntu SMP Wed May 7 23:31:02 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux Machine Type: x86_64-pc-linux-gnu Bash Version: 4.3 Patch Level: 11 Release Status: release Description: I write a bash script file containing variables definitions. From another bash script file, I source it from outside any function: in this case all is working fine as expected. Now, I source it from inside a function: I obtain following error message: bash: declare: tmp: not found I think this problem raises in the particular case of involving array variables definitions inside sourced bash script file... Repeat-By: You can execute the script below: #!/bin/bash generate_file_to_be_sourced() { local file_to_be_sourced file_to_be_sourced="$(mktemp)" cat << "EOF" > "${file_to_be_sourced}" declare -a tmp='([0]="1" [1]="2")' EOF echo "${file_to_be_sourced}" } foo() { source "${g_file_to_be_sourced}" if declare -p tmp &> /dev/null && [ "${#tmp[@]}" = "2" ] then echo "test #2: OK" else echo "test #2: NOK" fi unset tmp } echo "bash version: ${BASH_VERSION}" echo declare -r g_file_to_be_sourced="$(generate_file_to_be_sourced)" echo "content of file to be sourced:" cat "${g_file_to_be_sourced}" echo source "${g_file_to_be_sourced}" if declare -p tmp &> /dev/null && [ "${#tmp[@]}" = "2" ] then echo "test #1: OK" else echo "test #1: NOK" fi unset tmp foo rm "${g_file_to_be_sourced}" If you need further informations, don't hesitate to ask me... Best regards Jean-Philippe
brace expansion fails in 4.3, succeed in 4.2
Configuration Information [Automatically generated, do not change]: Machine: x86_64 OS: linux-gnu Compiler: gcc Compilation CFLAGS: -DPROGRAM='bash' -DCONF_HOSTTYPE='x86_64' -DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='x86_64-unknown-linux-gnu' -DCONF_VENDOR='unknown' -DLOCALEDIR='/home/nbah/share/locale' -DPACKAGE='bash' -DSHELL -DHAVE_CONFIG_H -I. -I. -I./include -I./lib -g -O2 uname output: Linux myOwnMachine 3.2.0-4-amd64 #1 SMP Debian 3.2.57-3 x86_64 GNU/Linux Machine Type: x86_64-unknown-linux-gnu Bash Version: 4.3 Patch Level: 11 Release Status: release Description: bash-4.2 $ printf "%s " "$(date -d -"{0..9}"days +%Y%m%d)" 20140510 20140509 20140508 20140507 20140506 20140505 20140504 20140503 20140502 20140501 bash-4.3 $ printf "%s " "$(date -d -"{0..9}"days +%Y%m%d)" date: date non valide « -{0..9}days »
Manpage tweaks to clarify nameref behavior
Configuration Information [Automatically generated, do not change]: Machine: x86_64 OS: linux-gnu Compiler: gcc Compilation CFLAGS: -DPROGRAM='bash' -DCONF_HOSTTYPE='x86_64' -DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='x86_64-pc-linux-gnu' -DCONF_VENDOR='pc' -DLOCALEDIR='/usr/share/locale' -DPACKAGE='bash' -DSHELL -DHAVE_CONFIG_H -I. -I../. -I.././include -I.././lib -D_FORTIFY_SOURCE=2 -g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -Wall uname output: Linux jhaemer-ThinkPad-T420 3.13.0-24-generic #46-Ubuntu SMP Thu Apr 10 19:11:08 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux Machine Type: x86_64-pc-linux-gnu Bash Version: 4.3 Patch Level: 11 Release Status: release Description: The shell's behavior when exporting nameref variables isn't described clearly enough -- at least, to me -- by the manpage. Repeat-By: #!/bin/bash comment() { printf '\n== %s\n' "$@" } report() { echo "foo is '$foo' bar is '$bar'" } demo() { comment "$@" printf 'Shell: ' report printf 'Subshell: ' bash -c report } # don't export anything export -f report foo=bar; bar=69; export -n foo bar demo 'At first, export nothing' export foo demo 'Export only foo' export bar demo 'Export both variables' declare -n foo demo 'Make foo a nameref' unset foo bar demo 'Unset foo, then bar' comment '** Note: if I had unset bar first, then they would both be unset. **' declare +nx foo bar unset foo bar demo 'Reset everything from scratch' declare -n foo foo=bar; bar=69 demo 'Make foo a nameref to bar before exporting' export foo demo 'Export only foo' comment '** Note: The man page tweak is meant to describe this behavior. **' exit 0 Fix: - Under PARAMETERS, change this Whenever the nameref variable is referenced or assigned to, the operation is actually performed on the variable specified by the nameref variable's value. to this Whenever the nameref variable is referenced, assigned to, or exported, the operation is actually performed on the variable specified by the nameref variable's value. - Further on, change this References and assignments to ref are treated as references and assignments to the variable whose name was passed as $1. to this Exports, references, and assignments to ref are treated as exports, references and assignments to the variable whose name was passed as $1. (Yeah, I don't like the preposition either. If you can word it better, great!) - A third fix needs to be made, in SHELL BUILTIN COMMANDS, to the description of the "-n" option to "declare/typeset" . -- Jeffrey Haemer 720-837-8908 [cell], http://seejeffrun.blogspot.com [blog], http://www.youtube.com/user/goyishekop [vlog] *פרייהייט? דאס איז יאַנג דינען וואָרט.*
Re: brace expansion fails in 4.3, succeed in 4.2
On Saturday, May 10, 2014 02:35:44 PM NBaH wrote: > bash-4.2 $ printf "%s " "$(date -d -"{0..9}"days +%Y%m%d)" 20140510 > 20140509 20140508 20140507 20140506 20140505 20140504 20140503 > 20140502 20140501 > > bash-4.3 $ printf "%s " "$(date -d -"{0..9}"days +%Y%m%d)" date: date > non valide « -{0..9}days » This was a bug. Chet fixed it for 4.3. The inner brace expansion should not be evaluated because (non-backtick) command substitutions always produce a completely new context for evaluating commands. Since bash re-arranges Csh brace expansion to be first, it has to heuristically protect the applicable expansions that happen later from its effects. That's a hard problem. You can achieve the same effect in other ways by looping or with eval if appropriate. printf %()T is another possibility. I usually abuse the way Bash parses array subscripts. If ksh93 is available then a simpler solution is possible. $ bash -c 'printf -v a "%(%s)T" -1; printf "%(%Y%m%d)T " "$a" "${a[a+=60*60*24,0]"{0..8}"}"; echo' 20140510 20140511 20140512 20140513 20140514 20140515 20140516 20140517 20140518 20140519 $ ksh -c 'printf "%(%Y%m%d)T " "" -{1..9}\ days; echo' 20140510 20140511 20140512 20140513 20140514 20140515 20140516 20140517 20140518 20140519 -- Dan Douglas
Re: brace expansion fails in 4.3, succeed in 4.2
Le 10/05/2014 22:31, Dan Douglas a écrit : $ bash -c 'printf -v a "%(%s)T" -1; printf "%(%Y%m%d)T " "$a" "${a[a+=60*60*24,0]"{0..8}"}"; echo' 20140510 20140511 20140512 20140513 20140514 20140515 20140516 20140517 20140518 20140519 Thank you very much. This is tremendous! Do you mind explaining a little bit «the way Bash parses array subscripts» ?
Re: brace expansion fails in 4.3, succeed in 4.2
On Saturday, May 10, 2014 03:31:05 PM Dan Douglas wrote: > $ bash -c 'printf -v a "%(%s)T" -1; printf "%(%Y%m%d)T " "$a" "${a[a+=60*60*24,0]"{0..8}"}"; echo' > 20140510 20140511 20140512 20140513 20140514 20140515 20140516 20140517 20140518 20140519 By the way, I'm not very good at remembering the winking smiley when my solutions are not entirely serious, so here it is: ;-) Also, I didn't notice you meant to count backwards. GNU date has a better solution anyway by reading date formats with "-f". The downside is it appears to only do newline-delimited input and output. $ printf 'now - %d days\n' {0..9} | date -f - +%Y%m%d | tr '\n' ' '; echo 20140510 20140509 20140508 20140507 20140506 20140505 20140504 20140503 20140502 20140501 -- Dan Douglas
Re: brace expansion fails in 4.3, succeed in 4.2
On Saturday, May 10, 2014 11:28:44 PM NBaH wrote: > Do you mind explaining a little bit «the way Bash parses array > subscripts» ? > Didn't notice this reply (as I failed to mention, this is slightly ridiculous code. Use a loop for important code of course). It skips over any text between the closing bracket and parameter expansion operator (if any). That combined with referencing the zeroth element of an array being a synonym for the variable itself even if it doesn't have an array attribute. So that expands to: "${a[0]0}" "${a[0]1}" etc. Bash ignores the number after `]` and treats ${a[0]} as "$a". Meanwhile the math side-effect before the comma operator modifies a[0] as it goes. I've done worse. Here's a million args via plain brace expansion (not sequence expansion). Also possibly the only ever "practical" usage of GNU factor(1) (or at least the silliest). http://wiki.bash-hackers.org/syntax/expansion/brace#more_fun -- Dan Douglas