The UNIX and Linux Forums  
Hello and Welcome from United States to the UNIX and Linux Forums! Thank You for Visiting and Joining Our Global Community.

Go Back   The UNIX and Linux Forums > Top Forums > Shell Programming and Scripting
.
google unix.com



Shell Programming and Scripting Post questions about KSH, CSH, SH, BASH, PERL, PHP, SED, AWK and OTHER shell scripts and shell scripting languages here.

More UNIX and Linux Forum Topics You Might Find Helpful
Thread Thread Starter Forum Replies Last Post
Passing global variable to a function which is called by another function sars Shell Programming and Scripting 4 06-30-2008 11:39 AM
passing variable from bash to perl from bash script arsidh Shell Programming and Scripting 10 06-04-2008 12:25 PM
Help in passing array of inputs to C program using script? ahjiefreak Shell Programming and Scripting 1 03-20-2008 07:36 AM
passing variable to function Knotty UNIX for Dummies Questions & Answers 4 04-05-2007 12:49 AM
Parameter passing in a function fastgoon UNIX for Advanced & Expert Users 2 07-26-2006 05:10 AM

Closed Thread
English Japanese Spanish French German Portuguese Italian Dutch Swedish Russian Norwegian Hungarian Hebrew Danish Powered by Powered by Google
 
LinkBack Thread Tools Search this Thread Rate Thread Display Modes
  #1 (permalink)  
Old 04-16-2008
ripat ripat is offline Forum Advisor  
Registered User
  
 

Join Date: Oct 2006
Location: Belgium
Posts: 438
[BASH - KSH] Passing array to a function

Passing a array to a function, a basic feature in modern language, seems to be only possible in KSH. Not in BASH. Depite all my efforts I couldn't come to a solution. See the following examples:

It works perfectly in KSH:
Code:
#!/usr/bin/ksh

function print_array {
    # assign array by indirect variable reference (namerefs)
    typeset -n array=$1

    # display array content
    echo "${array[*]}"
}

colors=('Pink' 'Light Gray' 'Green')

print_array "colors"
But this one gave me headhache:
Code:
#!/bin/bash

function print_array {
    # trying to assign array by indirect variable reference
    declare -a array=${!1}
    # local array=${!1}         # doesn't work either

    # display array content
    echo "${array[*]}"
}

colors=('Pink' 'Light Gray' 'Green')

print_array "colors"
Some reference in the manual for using indirect reference in BASH:
http://tldp.org/LDP/abs/html/bashver2.html#VARREFNEW
  #2 (permalink)  
Old 04-16-2008
Perderabo's Avatar
Perderabo Perderabo is offline Forum Staff  
Unix Daemon
  
 

Join Date: Aug 2001
Location: Ashburn, Virginia
Posts: 9,111
This version works with ksh or bash.

Code:
#! /usr/local/bin/bash
#! /usr/bin/ksh

function print_array  {
        array_name=$1
        eval echo \${$array_name[*]}
        return
}

colors[0]="Pink"
colors[1]="Light Gray"
colors[2]="Green"

print_array colors
exit 0
  #3 (permalink)  
Old 04-17-2008
ripat ripat is offline Forum Advisor  
Registered User
  
 

Join Date: Oct 2006
Location: Belgium
Posts: 438
Hi Perderabo,

With my GNU bash, version 3.2.25 it only returns the array name "colors" but not its contents. I have also tried this trick:

Code:
function print_array {
    array_name="$1[*]"
    echo ${!array_name}
}
It returns the array elements (on one line) but the local array doesn't exists as such as I can not access it by doing something like:

Code:
function print_array {
    array_name="$1"
    echo ${!array_name[1]}
}
This always return the first element "pink" [0]. Of course I could access the array elements by doing:
Code:
function print_array {
    array_name="$1[0]"
    echo ${!array_name}

    array_name="$1[1]"
    echo ${!array_name}

    array_name="$1[2]"
    echo ${!array_name}
}
Which is rather inelegant and clumsy. All I wanted is to create a *local* copy of the array whose name is passed to the function as positional parameter ($1 $2 ....). By the way, how can I copy an array without looping throught it and assigning values one by one. Of course, the following doesn't work:
Code:
colors=('Pink' 'Light Gray' 'Green')
echo ${colors[@]}

copy_colors=$colors
echo ${copy_colors[@]}

# returns:
# Pink Light Gray Green (3 elements)
# Pink

copy_colors=(${colors[*]})
echo ${copy_colors[*]}
echo ${copy_colors[1]}

# "Light Gray" is split:
# Pink Light Gray Green (4 elements!)
# Light
I think I start to understand why members of this forum perfer ksh :=)

Last edited by ripat; 04-17-2008 at 07:21 AM..
  #4 (permalink)  
Old 04-17-2008
ripat ripat is offline Forum Advisor  
Registered User
  
 

Join Date: Oct 2006
Location: Belgium
Posts: 438
Boy, this one wasn't easy!

OK, here is what works in bash. Remember, the question was to pass an array to a function and make sure that whatever is done by the function remains local. If the local scope isn't necessary, just remove the "local" declaration.
Code:
#!/bin/bash

function print_array {
    # Setting the shell's Internal Field Separator to null
    OLD_IFS=$IFS
    IFS=''

    # Create a string containing "colors[*]"
    local array_string="$1[*]"

    # assign loc_array value to ${colors[*]} using indirect variable reference
    local loc_array=(${!array_string})

    # Resetting IFS to default
    IFS=$OLD_IFS

    # Checking the second element "Light Gray" (the one with a space)
    echo ${loc_array[1]}
    
}

# create an array and display contents
colors=('Pink' 'Light Gray' 'Green')
echo ${colors[*]}

# call function with positional parameter $1 set to array's name
print_array colors 

# checking whether the function "local" loc_array is visible here
echo "Does the local array exist here? -->${loc_array[*]}<--"
exit 0
This returns:
Code:
Pink Light Gray Green
Light Gray
Does the local array exist here? --><--
We can also "copy" an array the same way: setting IFS to NULL permit to do variable expansion that preserves the possible spaces in array's elements.
Code:
colors=('Pink' 'Light Gray' 'Green')
OLD_IFS=$IFS
IFS=''
copy_colors=(${colors[*]})
IFS=$OLD_IFS

echo ${copy_colors[*]}
echo ${copy_colors[1]}

Last edited by ripat; 04-18-2008 at 02:35 AM..
Closed Thread

Bookmarks

Tags
bash, bash eval, eval

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On




All times are GMT -4. The time now is 10:57 AM.


Powered by: vBulletin, Copyright ©2000 - 2006, Jelsoft Enterprises Limited. Language Translations Powered by .
vBCredits v1.4 Copyright ©2007 - 2008, PixelFX Studios
The UNIX and Linux Forums Content Copyright ©1993-2009. All Rights Reserved.Ad Management by RedTyger

Content Relevant URLs by vBSEO 3.2.0