Debug is more boring, so here first on the conclusions and examples, Debug notes do not look and no confusion.
Conclusion
Using the return value in the shell, the only way to be universal is to use a global variable, or use Echo and receive it in the parent process.
The return statement cannot be used to pass the result of the calculation--return statement is used to pass the function exit state, in almost all cases, your calculation results will not be the exit status!
Any shell script that violates the above rules is not universal.
Example
#!/usr/bin/env Bash# ======================================# using Global variables# Pros: The return value can be passed correctly in all cases# Cons: Too many global variables can make the program difficult to read# ======================================Global_value="'function Make_value {# To do some calculations here:# Then set the global variableGlobal_value=' value ' # return error code return$?} Make_value# To determine if the function is performing successfullyif[[0!= $? ]]; Then Echo ' make_value execution failed ' Exit$?fi# Read the results stored in global variablesEcho "Now we get return value with $global _value"
#!/usr/bin/env Bash# ======================================# Passing the return value using the Echo statement# Pros: Correct delivery of return values while being highly readable# Cons: The function must not have any output to the stdout stream# ======================================function Make_value {# To do some calculations hereLocal local_value=' value ' # returns the calculated result Echo $local _value # return error code return$?} local_value=$ (Make_value)# To determine if the function is performing successfullyif[[0!= $? ]]; Then Echo ' make_value execution failed ' Exit$?fi# Read the results stored in global variablesEcho "Now we get return value with $local _value"
Debug
Recently changed the development environment to arch Linux, however, in recent days to recompile the project encountered a problem: make
in the process of a problem-free tool make_ext4fs
will be 0 errors, resulting in the generation of system.img is empty! This error is very deadly and low-level, and it is impossible to suddenly present a deadly and low-level problem in a well-run tool.
Trace the location of the call make_ext4fs
and find it in line No. 219 of the script sprdisk/utils/build64.sh :
-T-1-S$ANDROID_PRODUCT_OUT-l$syssize-a$ANDROID_PRODUCT_OUT/obj/PACKAGING/systemimage_intermediates/system.$ANDROID_PRODUCT_OUT/system
The variable $android_product_out is source build/envsetup.sh
determined after that, only the value of $syssize is determined at run time, and the value of this variable is printed. is an indeterminate number, the initial judgment range is between 0-200. Use the value of $syssize to manually construct instructions to run, except for the 0 error must be present.
Trace $syssize source, found to be set by the return value of the function get_system_img_size
get_system_img_size syssize=$?
Printed a few times this return value, the range conforms to the initial judgment scope, constructs the instruction with these return values, except the 0 error must present.
Tracking $syssize calculation process, found that this value originates from the file $android_product_out/obj/packaging/systemimage _intermediates/system_image_info.txt, set by the system_size field
while ReadLine Doitem=$ (Echo $line| (awk-f"=" ' {print '} ') | Tr- D "')if[$item="System_size"] ; Thensyssize=$ (Echo $line| (awk-f"=" ' {print $} ') | Tr- D "') ramdisksize=$ (Echo$ (du-b$TOPDIR/RAMDISK.IMG) | (awk' {print$1} ') | Tr- D "') syssize=$ (expr$syssize+$ramdisksize) Break fi Done<$sysinfo
grep this file, found that the value of the system_size field is close to 600 million, that is, above 550MB
system_size=596555857
The command is constructed with this value make_ext4fs
and executed successfully. Determine the problem out of the variable $syssize.
The value of the variable is printed inside the function, and it is found that the value is correct when the function returns, and the locking problem occurs on the receipt of the function return value, which is the two lines mentioned earlier
get_system_img_size syssize=$?
Before finishing the situation, master the following conditions:
- The return value has changed after the function call
- A change in the return value causes a
make_ext4fs
0 error to occur
- This issue does not appear on Ubuntu Kylin, and must be present on arch Linux
Determine if the function return value is caused by an environmental problem, first suspect the shell is different, so determine the script shebang line
#!/bin/sh
Confirm on the arch Linux once /bin/sh
, find pointing /usr/bin/bash
;
Borrow a colleague's Ubuntu Kylin to confirm /bin/sh
it again and find the point /usr/bin/dash
!
Sorting out the information
- The problem is that the function return value is not properly received
- Was
bash
and dash
led to this difference
Because there is no installation dash
, the first confirmation bash
on the situation, man 1 bash
found the following information
The return value of a simple command was its exit status, or 128+n if the command was terminated by Signal N.
This value is obviously only 500 million.
In fact, the test proves that bash
the return
statement long can return 255 of the shaping, any more than 255 of the return value, will be and 255 modulo and return the value after the modulo.
Instead of dash
processing the return value and bash, the value after the return statement is returned intact.
This is why the return value has changed: in the shell design, the return
statement is used to pass the error code instead of the return value, so different shells return
have different handling of the statement.
This also comes to the conclusion that the statement in the shell script return
can only be used to return the error code, never return any calculation results, which does not conform to the design principle of the shell, so it is not universal.
Finally, for the sake of preserving the global settings of the system, the modification script uses the echo
statement to pass the return value and compile the pass.
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
How to correctly transfer function return values in the shell