How to return a string value from a Bash function
There is no better way I know of. Bash knows only status codes (integers) and strings written to the stdout.
shell script function return a string
The first is calling the function and storing all of the output (four echo
statements) into $constr
.
Then, after return, you echo the preamble printing result
, $constr
(consisting of four lines) and the exit message.
That's how $()
works, it captures the entire standard output from the enclosed command.
It sounds like you want to see some of the echo
statements on the console rather than capturing them with the $()
. I think you should just be able to send them to standard error for that:
echo "String1 $1" >&2
bash: how to return string with newline from function?
Use printf
to print formatted strings.
create_string() {
printf '[%s]\nworld\n' "$1"
}
Bash: Return a string from bash function
The return
statement used by bash
is used to return a numeric value as a status code to be retrieved through $?
by the calling function. You can not return a string. See also
- Returning Values from Bash Functions
- How to return a string value from a Bash function
You can either use a special global variable as proposed by @konsolebox, or echo
the return value inside your function, and use command substitution when calling the function:
makeName()
{
echo "$fileName.$1.log"
}
echo -n "Enter fileName:"
read fileName
name1=$(makeName "type1")
name2=$(makeName "type2")
echo $name1
echo $name2
[UPDATE]
The updated question shows that you intend to read yet another value inside the makeName
function, while the function also intends to echo
some prompt for the user. So the command substitution approach will not work in that case - you need to use a global variable, like
makeName() {
echo -n "Enter Ext: "
read ext
__="$fileName.$1.$ext.log"
}
echo -n "Enter fileName:"
read fileName
makeName "type1" ; name1=${__}
makeName "type2" ; name2=${__}
echo $name1
echo $name2
$ ./sample.sh
Enter fileName:filename
Enter Ext: ext1
Enter Ext: ext2
filename.type1.ext1.log
filename.type2.ext2.log
Yet better, for cleaner code and to avoid using global variables inside your function, you could use the approach described at Returning Values from Bash Functions and pass the name of the return variable as parameter, and ideally also pass the fileName
as parameter:
makeName() {
local __type=$1
local __fileName=$2
local __resultvar=$3
local ext
local myresult
echo -n "Enter Ext: "
read ext
myresult="$__fileName.$__type.$ext.log"
eval $__resultvar="'$myresult'"
}
echo -n "Enter fileName:"
read fileName
makeName "type1" $fileName theResult ; name1=${theResult}
makeName "type2" $fileName theResult ; name2=${theResult}
echo $myresult
echo $name1
echo $name2
Side Note: See Why should eval be avoided in Bash, and what should I use instead? for a discussion why eval
should be avoided. When using bash version 3.1 or higher, you can use printf
instead of eval
:
...
printf -v "$__resultvar" '%s' "$myresult"
...
And, finally, with bash 4.3 or higher, we can assign the nameref attribute to a variable using declare -n
, so that the variable is effectively a reference to another variable:
...
declare -n myresult=$3
myresult="$__fileName.$__type.$ext.log"
...
Returning value from called function in a shell script
A Bash function can't return a string directly like you want it to. You can do three things:
- Echo a string
- Return an exit status, which is a number, not a string
- Share a variable
This is also true for some other shells.
Here's how to do each of those options:
1. Echo strings
lockdir="somedir"
testlock(){
retval=""
if mkdir "$lockdir"
then # Directory did not exist, but it was created successfully
echo >&2 "successfully acquired lock: $lockdir"
retval="true"
else
echo >&2 "cannot acquire lock, giving up on $lockdir"
retval="false"
fi
echo "$retval"
}
retval=$( testlock )
if [ "$retval" == "true" ]
then
echo "directory not created"
else
echo "directory already created"
fi
2. Return exit status
lockdir="somedir"
testlock(){
if mkdir "$lockdir"
then # Directory did not exist, but was created successfully
echo >&2 "successfully acquired lock: $lockdir"
retval=0
else
echo >&2 "cannot acquire lock, giving up on $lockdir"
retval=1
fi
return "$retval"
}
testlock
retval=$?
if [ "$retval" == 0 ]
then
echo "directory not created"
else
echo "directory already created"
fi
3. Share variable
lockdir="somedir"
retval=-1
testlock(){
if mkdir "$lockdir"
then # Directory did not exist, but it was created successfully
echo >&2 "successfully acquired lock: $lockdir"
retval=0
else
echo >&2 "cannot acquire lock, giving up on $lockdir"
retval=1
fi
}
testlock
if [ "$retval" == 0 ]
then
echo "directory not created"
else
echo "directory already created"
fi
Return value in a Bash function
Although Bash has a return
statement, the only thing you can specify with it is the function's own exit
status (a value between 0
and 255
, 0 meaning "success"). So return
is not what you want.
You might want to convert your return
statement to an echo
statement - that way your function output could be captured using $()
braces, which seems to be exactly what you want.
Here is an example:
function fun1(){
echo 34
}
function fun2(){
local res=$(fun1)
echo $res
}
Another way to get the return value (if you just want to return an integer 0-255) is $?
.
function fun1(){
return 34
}
function fun2(){
fun1
local res=$?
echo $res
}
Also, note that you can use the return value to use Boolean logic - like fun1 || fun2
will only run fun2
if fun1
returns a non-0
value. The default return value is the exit value of the last statement executed within the function.
Can a string be returned from a Bash function without using echo or global variables?
No. Bash doesn't return anything other than a numeric exit status from a function. Your choices are:
- Set a non-local variable inside the function.
- Use
echo
,printf
, or similar to provide output. That output can then be assigned outside the function using command substitution.
Return exactly one string/value from shell script
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
Related Topics
Check If There Is an Stdout Redirection in Bash Script
How to Detect a Buffer Over Run on Serial Port in Linux Using C++
Run Jenkins Jobs on Linux Under a User
Module Compiling:Asm/Linkage.H File Not Found
Prevent Process from Killing Itself Using Pkill
Object-Oriented Shell for Linux
Linux Terminal: How to Capture or Watch Other Terminal Session
Parse CSV in Bash and Assign Variables
How to Speed Up Compilation Time in Linux
List Files Recursively in Linux Cli With Path Relative to the Current Directory
A Way to Determine a Process'S "Real" Memory Usage, I.E. Private Dirty Rss
How to Write Full-Screen Linux Console App/Script
Ssh Command Execution Hangs, Although Interactive Shell Functions Fine
How to Calculate the Total Size of Certain Files Only, Recursive, in Linux
Interrupting Epoll_Wait with a Non-Io Event, No Signals
Output the 2Nd Column of a File