Home > OS >  Manipulating content of a variable argument in bash
Manipulating content of a variable argument in bash

Time:12-15

I'm a beginner at bash. There are a lot of similar question to that question, but I didn't manage to find one addressing that specific situation.

The concatenating problem is just an imaginary context to illustrate the real issue, which is: Bash functions can only return integers between 0 and 255. Please don't comment "bash can concatenate strings natively using x command" that's not the core of my issues.

I came up with a "workaround" for that problem, using an auxiliary variable for storing the string result of a function that needs to return a string.

function concatenate(){
    echo "Arg1: $1 Arg2: $2 Arg3: $3"
    $1="$1$2$3"
}

result="a"
concatenate "$result" "hello" " world!"

echo $result

$1 is a reference to the first argument (result variable). $2, a reference to the second argument. $3, third argument.

I think I managed to pass the arguments I wanted to the function, as echo printed them correctly. However I'm not managing to change $1, result value, it throws an error.

Arg1: a Arg2: hello Arg3:  world!
main.bash: line 8: a:=ahello world!: command not found
a

I also tried the = syntax as proposed here: How to concatenate string variables in Bash

function concatenate(){
    echo "Arg1: $1 Arg2: $2 Arg3: $3"
    $1 =$2
    $1 =$3
}

result="a"
concatenate "$result" "hello" " world!"

echo $result

But the error still persists:

Arg1: a Arg2: hello Arg3:  world!
main.bash: line 8: a =hello: command not found
main.bash: line 9: a =: command not found
a

I know many languages have an issue with changing an argument locally not changing it globally. I'm not sure if I'm using the wrong syntax, or if that's the case.

Could someone please help me? I would welcome very much if it's not the case my workaround is the proper for dealing with that kind of situation, and if someone can tell the proper one. Thanks a lot in advance!

CodePudding user response:

If your bash version is 4.3 or newer, you can use namerefs:

concatenate() { declare -n ref=$1; ref=$2$3; }

concatenate result "hello" " world!"
echo "$result"

And this version will concatenate any number of arguments:

concatenate() { local -n ref=$1; local IFS=""; ref=${*:2}; }

concatenate result "This" " version" " concatenates" " any" " number" " of" " arguments"
echo "$result"

CodePudding user response:

You need to use eval to execute an assignment with a dynamic variable.

And to get the old value of $a, you need to use an indirect variable: ${!1}

concatenate() {
    echo "Arg1: $1 Arg2: $2 Arg3: $3"
    eval "$1='${!1}$2$3'"
}

And when you call the function, you need to provide the name of the result variable literally:

concatenate result "hello" " world!"

P.S. There's no good reason to use the bash-specific function keyword. Use the standard function definition syntax.

  •  Tags:  
  • bash
  • Related