global variable value not set inside a function in shell script - bash

I have two shell script like as follows:
a.sh
tes=2
testfunction(){
tes=3
echo 5
}
testfunction
echo $tes
b.sh
tes=2
testfunction(){
tes=3
echo 5
}
val=$(testfunction)
echo $tes
echo $val
In first script tes value is '3' as expected but in second it's 2?
Why is it behaving like this?
Is $(funcall) creating a new sub shell and executing the function? If yes, how can address this?

$() and `` create new shell and return output as a result.
Use 2 variables:
tes=2
testfunction(){
tes=3
tes_str="string result"
}
testfunction
echo $tes
echo $tes_str
output
3
string result

Your current solution creates a subshell which will have its own variable that will be destroyed when it is terminated.
One way to counter this is to pass tes as a parameter, and then return* it using echo.
tes=2
testfunction(){
echo $1
}
val=$(testfunction $tes)
echo $tes
echo $val
You can also use the return command although i would advise against this as it is supposed to be used to for return codes, and as such only ranges from 0-255.Anything outside of that range will become 0
To return a string do the same thing
tes="i am a string"
testfunction(){
echo "$1 from in the function"
}
val=$(testfunction "$tes")
echo $tes
echo $val
Output
i am a string
i am a string from in the function
*Doesnt really return it, it just sends it to STDOUT in the subshell which is then assigned to val

Related

Interpret return value of bash function

I would like to interpret the return value of the function a in the parent bash.
I want to use return to stop an intermediate script in the parent bash.
In this case it means, that test2 shouldn't be executed.
But it doesn't work.
And I don't want to use exit, because it stops "everything" in the parent process.
Does exist a solution to do that?
Script:
#!/bin/bash
function a {
return 1
}
echo "test1"
a
echo "test2"
Output:
test1
test2
The output should be just
test1
Perhaps you want
#!/bin/bash
a() {
return 1
}
echo "test1"
if ! a; then
echo "test2"
fi
Or for short
echo "test1"
a || echo "test2"
It seems that set -e can do what you want :
#!/usr/bin/env bash
set -e
function a {
return 1
}
echo "test1"
a
echo "test2"
set -e might be a "bad idea" : https://mywiki.wooledge.org/BashFAQ/105#Exercises

Clearing the echo history

I have a bash script that calls a function which returns a value. I have included the scripts below:
Script
source ./utilities/function1.sh
result=$(Function1)
echo "Result: $result"
Function1
function Function1 {
echo "Inside Function: Function1"
cat <<EOF
this is the result
EOF
}
I want to be able to echo to the console within the function and return only the value I want, not including the messages that were echoed to the console, but when I run the script the following is returned:
Result: Inside Function: Func1
this is the result
Is this the best way to return a value from a bash function or is there a way I can echo to the console and return a value without the content of the echo commands from the function?
Thanks in advance
There are a few ways to do what you want. two simple ones are:
Use STDERR to echo to the console and capture STDOUT in your script. By default, STDOUT is on File Descriptor 1 and STDERR is on File Descriptor 2:
function myFunction() {
echo "This goes to STDOUT" >&1 # '>&1' is the default, so can be left out.
echo "This goes to STDERR" >&2
}
result=$(myFunction)
echo ${result}
Use a variable to return a string to the caller:
function myFunction() {
echo "This goes to STDOUT"
result="This goes into the variable"
}
declare result="" # Has global scope. Can be modified from anywhere.
myFunction
echo ${result}
Global scope variables are not good programming practice, but are a necessary evil in bash scripting.

Using global variables in functions with parameters in bash

I'm trying to catch a return value from a function in bash, that modify a global variable.
Works perfectly with funtions with no parameters:
#!/bin/bash
tes=2
testfunction(){
tes=3
tes_str="string result"
return 0
}
if output=testfunction; then
echo "OK"
else
echo "KO"
fi
echo $tes
echo $tes_str
But no with parameters:
#!/bin/bash
tes=2
testfunction(){
tes=3
tes_str="string result"
return 0
}
if output=$(testfunction "AA" "BB"); then
echo "OK"
else
echo "KO"
fi
echo $tes
echo $tes_str
Because for bash, parameters ("AA" or "BB") are a command, and I must put it in backets (but if use backets, can't modify global variables).
How can I do it? I'm stucked.
Regards
Why use output? Just remove it and run the function.
if testfunction; then
Notes:
output=testfunction is assigning the text testfunction to the variable output.
output=$(testfunction) will not work, because $(...) runs everything inside a subshell.

capturing a string return value from one function in bash into another

I am trying to send a string as a return value from a function which is being called by another function in a different file. One sources the other.
The code is, like so:
#####################################################
##filename: conf_abc.menu
#######################################################
#!/bin/bash
source <path>/conf_pqr.menu
function abc () {
var=$(call_pqr)
echo ${var}
}
##Calling function abc
abc
#########################################################
##filename: conf_pqr.menu
########################################################
#!/bin/bash
RET_VAL=""
function get_intf() {
cmd=`some command`
RET_VAL=${cmd}
}
function call_pqr () {
comm=$(array of choices)
for choice in $comm
do
case $choice in
IF)get_intf;
echo "$RET_VAL";;
esac
done
}
I expect to see the choice from the array in "var" of function abc().
But the "echo ${var}" in conf_abc.menu does not print anything.
I run the script by doing:
./conf_abc.menu
What am I doing wrong?
Thanks for the comments. I found that when the return is called from the function, the entire output from echo is captured into the return variable. I then filtered the output using ">&2". I find that I do get the proper return string.
This I found from:
stackoverflow.com/questions/11758368/shell-script-function-return-a-string
I have put in a minimal example here:
##**file: vlan_menu.sh**
#!/bin/bash
source <path>/ifs_menu.sh
function conf_vlan () {
echo "Calling function if_menu" >&2
local output1=$(if_menu);
echo "printing result" >&2
ENET1="${output1}"
echo "ENET1 is= "${ENET1}"" >&2
}
conf_vlan; --> calling the main function
##**file: ifs_menu.sh**
#!/bin/bash
RET_VAL=""
function get_if() {
PI=$1
local var1=$(shell command)
if [ ! -z "${PI}" ]
then
local var2=<do something with var1>
else
local var2=<do something with var1>
fi
local cmd=$(start shell utility)
RET_VAL=${cmd}
}
function if_menu() {
comm=(1 2 3 4 5)
for choice in ${comm}
do
case $choice in
1) echo "IF" >&2;
get_if "";
echo "${RET_VAL}";;
2) echo "SF" >&2;
get_if $1;
echo "${RET_VAL}";;
esac
done
}
After running "vlan_menu.sh" script file, the value of "ENET1" is the same as "RET_VAL" which is what I wanted to see.
-rsmitha.

Return exactly one string/value from shell script

I have read qns regarding return output from a function in Stack Overflow. All the post says to use echo
#!/bin/bash
function myown()
{
echo "i dont need this in retval"
echo "Need this alone in retVal"
}
retVal=$(myown)
echo $retVal
o/p:
i dont need this in retval Need this alone in retVal
expected:
Need this alone in retVal
Is there a way to flush the previous output in echo. Or I need to parse all the echoed output to get my return value ? Is there simple way to do this ? Because I may have echos that are useful to debug and echo to return a value.
Echo output to stderr for debugging:
#!/bin/bash
function myown()
{
echo "i dont need this in retval" >&2
echo "Need this alone in retVal"
}
retVal=$(myown)
echo "result: $retVal"
When you run the script, you will see
i dont need this in retval
result: Need this alone in retVal

Resources