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
Related
There are two shell functions like belows
function call_function {
func=$1
desc=$2
log_file=$3
$func >> ${log_file} 2>&1
...
}
function echo_str {
str=$1
echo "$str"
}
How can I pass a shell function with parameters as a parameter?
I tried this:
call_function $( echo_str "test" ) "Echoing something" /var/logs/my_log.log
but only got
command not found
I googled it but nothing helps.
Thanks a lot in advance!
If you want to do this right, reorder your arguments to put the function to call last, and use shift to pop off the other arguments -- which will leave the function to call and its arguments in the "$#" array.
call_function() {
local log_file desc
log_file=$1; shift || return
desc=$1; shift || return
"$#" >>"$log_file" 2>&1
}
echo_str() {
local str
str=$1
echo "$str"
}
# log_file desc func args
call_function myfile.log "a function to echo something" echo_str "string to echo"
call_function $( echo_str "test" ) "Echoing something" /var/logs/my_log.log
This $( echo_str "test" ) call will execute echo_str "test" which will result in test, so call_function will execute:
test >> /var/logs/my_log.log 2>&1
So, you either create a dedicated function to log messages easily to a log file:
log_msg() {
current_date=$(date -u)
echo "[$current_date] $1" >> $2
}
or change call_function as suggested by #Darkman
I have the following program.sh:
#!/bin/bash
(true && { echo true1; echo true2; TEST=1; } || { echo false1; echo false2; TEST=0; }) >> program.log
echo test: $TEST
Why the output of program.sh is:
test:
What is a workaround to persist value in TEST?
Using parentheses creates a subshell. Variable assignments in a subshell don't propagate back to the parent shell. Try replacing () with {}.
{ true && { echo true1; echo true2; TEST=1; } || { echo false1; echo false2; TEST=0; }; } >> program.log
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.
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
Say I have the following two Bash scripts:
Version #1:
#!/bin/bash
function bar
{
if true; then
echo "error" >&2
exit 1
fi
echo "bar"
}
function foo
{
local val=`bar`
echo $?
echo "val: $val"
}
foo
With version #2 second having a slightly different foo:
function foo
{
val=`bar` #note no 'local'
echo $?
echo "val: $val"
}
Version #1 gives me the following output:
error
0
val:
Whilst version #2 gives me this:
error
1
val:
The inclusion of local in #2 appears to hide the return value of bar.
Am I correct in thinking this is because local is itself a function, and is returning 0? And if so, is there a way around this and make val a local variable, but still test the return value of bar?
Yes, you are reading the return value of local which was successful. The fix is to separate the variable declaration from its definition like so:
#!/bin/bash
function bar
{
if true; then
echo "error" >&2
exit 1
fi
echo "bar"
}
function foo
{
local val
val=$(bar)
echo $?
echo "val: $val"
}
foo
Output
$ ./localtest
error
1
val: