associative array assignment from the output of a function
Hello I try to assign an array from the output of a function. As this works for indexed arrays, it does not for associative arrays. I m using "GNU bash, version 4.1.7(1)-release (x86_64-redhat-linux-gnu)" on a Fedora 13 system. An easy example is better than an explanation: # Woks well indexarray() { echo "5 6 7" } declare -a t1=( $(indexarray) ) echo ${t1[1]} ${t1[0]} # Does not work assocarray() { echo "[a]=5 [b]=6" } declare -A t1=( $(assocarray) ) # The error occurs here The given error message is "cannot convert indexed to associative array". Is this behaviour intended ? Is there a known workaround for this ? I didnt find any "users" maling-list and I m not really sure this one fit to my message, since this may (or may not) be a bug report. Thanks for your answers, regards.
Re: associative array assignment from the output of a function
Le 22/10/2010 14:42, Greg Wooledge a écrit : Unreliable at best. How do you handle elements that have whitespace in them, for example? You have to know your data set, choose a delimiter that can't be in that set, and then write code to parse the output stream into elements. At this moment, I "solve" the problem of whitespace with a custom IFS : func() { echo "value 1\x1Evalue2" } IFS=$'\x1E' myvar=( $(func) ) Ick. You're attempting to use the language's internal assignment syntax in *data*. Sounds like you're on the road to eval, and we all know where *that* one ends! What you appear to be attempting to do is "return an associative array from a function to the caller". Bash's functions aren't really *functions* in the mathematical sense, or even in the sense of most high-level computing languages. They are really commands. User-definable commands. They don't return data. They only return an exit status. But that's a tangent. Anyway, if you want to make it so that after the function has returned, the caller has a brand new associative array, then what you need to do is: 1) Pre-declare the associative array in the CALLER, not in the function, because it is currently not possible for a function to create an associative array in the global namespace. AAs have to be created by using "declare", and if you use "declare" inside a function, it makes a local variable. Chet has said there will be a workaround for this in bash 4.2. 2) Inside the function, put the data into the AA. No, you can't pass the name of the array from the caller to the function either. You must HARD-CODE the array's name in the function. 3) Make sure you do NOT call the function in a subshell. Any attempts to return advanced data structures from a function using the techniques you'd expect in a high-level language just won't work in bash. It's a shell. It's not designed for this kind of task. Just use a global variable and be happy. Even if such needs of complex values built by functions are somewhat unusual (or even just a bad idea), I came to the same conclusion to use a global variable. Thanks a lot for your answer, I ll be happy with a global variable. Anyway, since this syntax works for assigning indexed arrays (even if it's a "hack"), should it works for associative array assignment ? Maintainers will decide I assume.
Re: associative array assignment from the output of a function
Le 22/10/2010 14:56, Chet Ramey a écrit : And you're trying to redeclare it as an associative array here. The variable already exists; you can't convert it between array types; and bash tells you this. If you want an associative array, unset the variable before you declare it. After your answer, I checked and I think the error message is not related to the variable name collision : [a...@axel-asus plugins]$ unset foo [a...@axel-asus plugins]$ func() > { > echo "[a]=5 [b]=10" > } [a...@axel-asus plugins]$ declare -A foo=( $(func) ) -bash: foo: [a]=5: must use subscript when assigning associative array -bash: foo: [b]=10: must use subscript when assigning associative array [a...@axel-asus plugins]$ echo ${foo[a]} [a...@axel-asus plugins]$ declare -a bar=( $(func) ) [a...@axel-asus plugins]$ echo ${bar[0]} [a]=5
Re: associative array assignment from the output of a function
Le 22/10/2010 16:21, Greg Wooledge a écrit : On Fri, Oct 22, 2010 at 02:59:37PM +0200, Axel wrote: Anyway, since this syntax works for assigning indexed arrays (even if it's a "hack"), should it works for associative array assignment ? Maintainers will decide I assume. But it doesn't. You used a totally different syntax for your indexed array example. If you had used the same syntax, it would have looked like this: imadev:~$ unset array imadev:~$ f() { echo '[0]=alpha [2]=beta'; }; array=( $(f) ) imadev:~$ set | grep ^array= array=([0]="[0]=alpha" [1]="[2]=beta") It doesn't "work" in the indexed array case either. Ok I see what you mean, finally it works only for indexed arrays without explicit indexes. I understand that point. There's another hazard you haven't taken into account (although it's only a hazard when dealing with general strings; numbers are safe). The unquoted substitution $(f) is subject to both word-splitting (which you've been taking advantage of) *and* globbing. imadev:~$ f() { echo '+ - * /'; }; array=( $(f) ) imadev:~$ echo "${array[42]}" baz imadev:~$ echo "${array[54]}" blah.txt imadev:~$ echo ${#arr...@]} 901 If you're going to use array=( $... ) with arbitrary strings being possible in the substitution, then you should disable globbing first (with set -f) to avoid potential disasters. Thanks again for those advices. Regards
weird insert of backslashes in strings
Configuration Information [Automatically generated, do not change]: Machine: i686 OS: linux-gnu Compiler: gcc Compilation CFLAGS: -fstack-protector -Wno-parentheses -Wno-format-security uname output: Linux bongo 2.6.32-042stab134.8 #1 SMP Fri Dec 7 17:16:09 MSK 2018 i686 i686 i386 GNU/Linux Machine Type: i686-pc-linux-gnu Bash Version: 5.0 Patch Level: 0 Release Status: release Description: This script "weirdbackslashes": $ cat weirdbackslashes #===begin PRE='\/' echo 'define'${PRE}'\ /' #===end produces with bash4: $ bash weirdbackslashes define\/\ / and with bash5: $ bash5 weirdbackslashes \d\e\f\i\n\e\/\\\ / Repeat-By: see Description
bash --login in Cygwin environment does not use %HOME% when doing tilde expansion.
Configuration Information [Automatically generated, do not change]: Machine: i686 OS: cygwin Compiler: i686-pc-cygwin-gcc Compilation CFLAGS: -DPROGRAM='bash.exe' -DCONF_HOSTTYPE='i686' -DCONF_OSTYPE='cygwin' -DCONF_MACHTYPE='i688 6-pc-cygwin' -DCONF_VENDOR='pc' -DSHELL -DHAVE_CONFIG_H -DRECYCLES_PIDS -I. -I/home/RLandheer/cygwin-contrr ib/bash/2.05b-16/bash-2.05b -I/home/RLandheer/cygwin-contrib/bash/2.05b-16/bash-2.05b/include -I/home/RLandhh eer/cygwin-contrib/bash/2.05b-16/bash-2.05b/lib -O2 uname output: CYGWIN_NT-5.0 WORK-ABB 1.5.10(0.116/4/2) 2004-05-25 22:07 i686 unknown unknown Cygwin Machine Type: i686-pc-cygwin Bash Version: 2.05b Patch Level: 0 Release Status: release Description: When invoking bash on a Windows machine with the --login option, tilde expansion is not done using the %HOME% environment variable. Repeat-By: Set HOME in the ControlPanel>System>Advanced>EnvironmentVariables>User variables for abb Invoke bash by calling bash.bat containing: @echo off c: chdir C:\bin\cygwin\bin bash --login -i Axel B. Bregnsbo ASIC Designer, M.Sc.EE +45 44855990 [EMAIL PROTECTED] -- entropy is time symmetric ___ Bug-bash mailing list Bug-bash@gnu.org http://lists.gnu.org/mailman/listinfo/bug-bash