How to correctly transfer function return values in the shell

Source: Internet
Author: User
Tags shebang arch linux

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:

    1. The return value has changed after the function call
    2. A change in the return value causes a make_ext4fs 0 error to occur
    3. 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

    1. The problem is that the function return value is not properly received
    2. 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

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.