user2813853
user2813853

Reputation:

Pass arguments to shell function by reference

I have a function to which Iam trying to send the array elements-

for (( idx=5 ; idx < ${#arr[*]} ; idx++ )); do
            escape_html ${arr[idx]} 
    done
function escape_html() {
x=$1
out="${x/>/%gt;}"
out="${x/</%lt;}"
}

I want the value of the array element to be changed if they have > or < after the function call (just as we use in call by reference). In this code, Iam passing the value to another variable. Idont want to do that. I want to do such operations directly on my argument and want those changes to be reflected the next time I try to access those array elements

Upvotes: 1

Views: 1524

Answers (2)

that other guy
that other guy

Reputation: 123600

If you want to do this correctly, have the loop update its own reference with array[idx]=$(yourfunction "${array[idx]}").


If you really want to do it the way you propose anyways, which is bad practice and has some caveats related to special variables and scope, pass the name and index rather than the value, then assign and reference indirectly:

#!/bin/bash
modify_arguments() {
  local var=$1
  local value=${!var}
  printf -v "$var" "${value//foo/bar}"
}

array=(food foodie fool fooled)

echo "Before: $(declare -p array)"
for i in {2..3}
do
  modify_arguments "array[i]"
done
echo "After:  $(declare -p array)"

Outputs:

Before: declare -a array='([0]="food" [1]="foodie" [2]="fool" [3]="fooled")'
After:  declare -a array='([0]="food" [1]="foodie" [2]="barl" [3]="barled")'

Upvotes: 2

Cyrus
Cyrus

Reputation: 88829

Variable idx and array arr are globals, no need to pass to function.

#!/bin/bash

function escape_html() {
  arr[idx]="${arr[idx]/>/%gt;}"
  arr[idx]="${arr[idx]/</%lt;}"
}

arr=(foo foo foo foo foo "<html>" "<xml>" "<bar>")

for (( idx=5 ; idx < ${#arr[*]} ; idx++ )); do
  echo ${arr[idx]}         # before function call
  escape_html
  echo ${arr[idx]}         # after funtion call
done

Upvotes: 1

Related Questions