Bashed!: Getting the function return as an array.
I want to:
You want to get an array back from a function (which exposes your underlying evil intentions)…
How the hell?
get_haxlog_types() { declare -a types types[0]="TRACE" types[1]="DEBUG" types[2]="INFO" types[3]="WARN" types[4]="ERROR" echo "${types[@]}" } logTypes=( `get_haxlog_types` ) echo "${logTypes[@]}" echo "${logTypes[0]}" echo "${logTypes[2]}"
WhaaaaaaAAAAA?
The above is a slightly modified function from one of my open source bash projects. To see this work, you will need to put the above into a file, and then make that file executable (like [code]]czoyMDpcImNobW9kIDc3NyBbZmlsZW5hbWVdXCI7e1smKiZdfQ==[[/code] or some such).
There are two parts to this solution – how the function returns and how you assign output of the function to a variable. Let’s start with how the function returns. I’m going to tell you something that will blow your mind here, so try not to utter primal screams and throw various innocent electronics devices around when the light shines. Ready? The return of the function has nothing to do with this.
Yeah – do you see a “return” statement anywhere in the code snippit above? No? That’s because we are not “returning” our array values – aaaand because functions return a numerical value specifying the success or lack thereof of the function execution. In simple terms, “0″ = good. Anything else = “AAAAaaaaahhhhhrrrrg!” The secret sauce of the solution to your problem is something that you are probably already doing if you’ve spent any time working with shell scripting. It’s all in the “echo”.
In a function, as in a shell script, the [code]]czo0OlwiZWNob1wiO3tbJiomXX0=[[/code] command is your best friend. Most of the time you are just echoing the value of a variable in your script in an attempt to figure out at just what point your code decided to hate you. In this case you are using the fact that the backtick command substitution will take the function name string ([code]]czoxNjpcImdldF9oYXhsb2dfdHlwZXNcIjt7WyYqJl19[[/code]) and run it as a script command, which then echos the contents of the array you created within that function.
The command substitution doesn’t finish the job, however. To see why, take away the subshell parenthesis and see what you’re left with. A little setup in the example script first:
logTypes=`get_haxlog_types` echo "${logTypes}" echo ${logTypes} echo "@ = ${logTypes[@]}" echo "0 = ${logTypes[0]}" echo "2 = ${logTypes[2]}"
… and then run the script. I’ve called my “test” because I have no imagination:
[root@vps tmp]# ./test TRACE DEBUG INFO WARN ERROR TRACE DEBUG INFO WARN ERROR @ = TRACE DEBUG INFO WARN ERROR 0 = TRACE DEBUG INFO WARN ERROR 2 = [root@vps tmp]#
What you’re left with is the array getting echoed in the function ([code]]czoxODpcImVjaG8gXCIke3R5cGVzW0BdfVwiXCI7e1smKiZdfQ==[[/code]) as one long string and being assigned to the [code]]czo4OlwibG9nVHlwZXNcIjt7WyYqJl19[[/code] variable, which is not what we are looking for. To get the echoed string assigned out as an array variable, we use ever useful subshell to get the string filtered through the IFS (internal field separator), which then breaks the string up by the spaces and assigns the now line break (LF) delimited string to the [code]]czo4OlwibG9nVHlwZXNcIjt7WyYqJl19[[/code] variable as an array, rather than a single string. Exempli gratia:
The set up, now with subshell secret sauce…
logTypes=(`get_haxlog_types`) echo "${logTypes}" echo ${logTypes} echo "@ = ${logTypes[@]}" echo "0 = ${logTypes[0]}" echo "2 = ${logTypes[2]}"
And the results we’ve wanted:
[root@vps tmp]# ./test TRACE TRACE @ = TRACE DEBUG INFO WARN ERROR 0 = TRACE 2 = INFO [root@vps tmp]#
That’s all there is to it.