Sync Post: http://blog.hacktons.cn/2017/12/13/shell-func-return/
Background
With Shell programming, custom functions are often required to write some tools for batch processing. In the case of more complex points, it may be necessary to return a value.
Because in the shell world, unlike other programming languages, it does not support the methods we are familiar with returning. This article summarizes how to gracefully solve the return value problem?
Test program
We generally $?
get the output from the previous statement. Take a look at the following test statement:
New testReturn
Script
returnString(){ return $1}returnString $1result=$?echo "result=$result"
Now we have a Testreturn script that has a returnstring method in it, and we want it to return directly to the parameters we have entered.
When we separate, hello
500
12
as input parameters, does his execution and output be the same?
./testReturn hello./testReturn 500./testReturn 12
Try to guess what's going on in your mind, now let's find out the answer:
Program Output Status
When the hello is executed, it does not output Hello, but returns a return that accepts only the number type error
aven-mac-pro-2:avenwu.github.io aven$ ./testReturn hello./testReturn: line 23: return: hello: numeric argument requiredresult=255
When executing 500, the page does not output 500, but it outputs 244
aven-mac-pro-2:avenwu.github.io aven$ ./testReturn 500result=244
Execute 12 when, finally correct, return 12
aven-mac-pro-2:avenwu.github.io aven$ ./testReturn 12result=12
Anomaly Analysis
Now we analyze returnstring This method, why there are so many output situation?
First of all, his writing is obviously not rigorous, but it is not completely wrong, such as input 12 he returned correctly.
return
itself is the shell inside the Buildin function, the author summarizes the next, he has the following several characteristics:
- Return returns a number state, often used to return 0, 1, to identify whether a function succeeded after execution
- Note that return cannot return a non-numeric type
- There is also a possibility of overflow in numeric types
Global variables
What if we just want to return a string? You can assign a value by defining a global variable, like the static variable/member variable, and I let his role penetrate the entire context scope.
result=""returnString(){ result=$1}returnString $1echo "result=$result"
Look at the output and get the results we need:
aven-mac-pro-2:avenwu.github.io aven$ ./testReturn helloresult=helloaven-mac-pro-2:avenwu.github.io aven$ ./testReturn 500result=500aven-mac-pro-2:avenwu.github.io aven$ ./testReturn 12result=12
This, however, pollutes the global variable, and the result variable is easily modified both internally and externally, resulting in internal modifications being invalidated.
Eval
Besides return
, there are some other Buildin keywords, such as eval
local
.
The variables defined by default in the current script are global variables, and local variables can be defined in the method by the locals, thus avoiding global variable contamination.
Combining the Eval assignment statement to implement the variable modification
returnString(){ local __result=$2 eval $__result=$1}returnString $1 resultecho "result=$result"
And we also get the results of hope.
aven-mac-pro-2:avenwu.github.io aven$ ./testReturn helloresult=helloaven-mac-pro-2:avenwu.github.io aven$ ./testReturn 500result=500aven-mac-pro-2:avenwu.github.io aven$ ./testReturn 12result=12
Echo
Finally, a method is introduced, which is echo
combined by output command substitution
.
This command substitution
did not find a more appropriate translation, let's translate it literally 命令替换
.
If your method has only one echo output inside, then you can also use her to make it worthwhile to return, but this is a bit of a limitation, make sure that there is only one output in the method, otherwise there will be too many assignments.
returnString(){ local __result=$1 echo $__result}# 或者 result=`returnString $1`result=$(returnString $1)echo "result=$result"
Can also get the expected results
aven-mac-pro-2:avenwu.github.io aven$ ./testReturn helloresult=helloaven-mac-pro-2:avenwu.github.io aven$ ./testReturn 500result=500aven-mac-pro-2:avenwu.github.io aven$ ./testReturn 12result=12
Cross-border issues
Now that we have several ways to return a string, the return number is sometimes correct and sometimes incorrect.
We know that return is used to return to the execution state, such as 0,1. Then when we return to 500, it is actually a data overflow.
According to the test, we infer that the shell's built-in return takes a byte size, that is, 8 bits, which can output unsigned 0-255, and all the data outside the range is displayed. Therefore, when you use return, be sure to pay attention to the value size.
Summary
The shell commands make it easy to write small scripts, but if you encounter logic complexity, it is recommended to do so with a more appropriate preview, such as Python,golang.
- Http://www.linuxjournal.com/content/return-values-bash-functions
Handling method return value problem in shell