Linux 在 bash 中,如何将返回值存储在变量中?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15013481/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 19:05:56  来源:igfitidea点击:

In bash, how to store a return value in a variable?

linuxbash

提问by itsh

I know some very basic commands in Linux and am trying to write some scripts. I have written a function which evaluates the sum of last 2-digits in a 5-digit number. The function should concatenate this resultant sum in between the last 2-digits and return it. The reason I want to return this value is because I will be using this value in the other function.

我知道 Linux 中的一些非常基本的命令,并且正在尝试编写一些脚本。我编写了一个函数,它计算 5 位数字中最后 2 位数字的总和。该函数应该在最后 2 位数字之间连接这个结果总和并返回它。我想返回这个值的原因是我将在另一个函数中使用这个值。

Ex: if I have 12345, then my function will calculate 4+5 and return 495.

例如:如果我有 12345,那么我的函数将计算 4+5 并返回 495。

#!/bin/bash

set -x
echo "enter: "
        read input

function password_formula
{
        length=${#input}
        last_two=${input:length-2:length}
        first=`echo $last_two| sed -e 's/\(.\)/ /g'|awk '{print }'`
        second=`echo $last_two| sed -e 's/\(.\)/ /g'|awk '{print }'`
        let sum=$first+$second
        sum_len=${#sum}
        echo $second
        echo $sum

        if [ $sum -gt 9 ]
        then
               sum=${sum:1}
        fi

        value=$second$sum$first
        return $value
}
result=$(password_formula)
echo $result

I am trying to echo and see the result but I am getting the output as shown below.

我正在尝试回显并查看结果,但得到的输出如下所示。

-bash-3.2$ ./file2.sh 
+++ password_formula
+++ echo 'enter: '
+++ read input
12385
+++ length=8
+++ last_two=85
++++ echo 85
++++ sed -e 's/\(.\)/ /g'
++++ awk '{print }'
+++ first=5
++++ echo 85
++++ sed -e 's/\(.\)/ /g'
++++ awk '{print }'
+++ second=8
+++ let sum=5+8
+++ sum_len=2
+++ echo 5
+++ echo 8
+++ echo 13
+++ '[' 13 -gt 9 ']'
+++ sum=3
+++ value=835
+++ return 835
++ result='enter: 
5
8
13'
++ echo enter: 5 8 13
enter: 5 8 13

I also tried to print the result as:

我还尝试将结果打印为:

password_formula
RESULT=$?
echo $RESULT

But that is giving some unknown value:

但这给出了一些未知的价值:

++ RESULT=67
++ echo 67
67

How can I properly store the correct value and print (to double check) on the screen?

如何正确存储正确的值并在屏幕上打印(仔细检查)?

Thanks in advance.

提前致谢。

回答by that other guy

The return value (aka exit code) is a value in the range 0 to 255 inclusive. It's used to indicate success or failure, not to return information. Any value outside this range will be wrapped.

返回值(又名退出代码)是 0 到 255 范围内的值。它用于指示成功或失败,而不是返回信息。超出此范围的任何值都将被换行。

To return information, like your number, use

要返回信息(例如您的电话号码),请使用

echo "$value"

To print additional information that you don't want captured, use

要打印您不想捕获的其他信息,请使用

echo "my irrelevant info" >&2 

Finally, to capture it, use what you did:

最后,要捕获它,请使用您所做的:

 result=$(password_formula)

In other words:

换句话说:

echo "enter: "
        read input

password_formula()
{
        length=${#input}
        last_two=${input:length-2:length}
        first=`echo $last_two| sed -e 's/\(.\)/ /g'|awk '{print }'`
        second=`echo $last_two| sed -e 's/\(.\)/ /g'|awk '{print }'`
        let sum=$first+$second
        sum_len=${#sum}
        echo $second >&2
        echo $sum >&2

        if [ $sum -gt 9 ]
        then
               sum=${sum:1}
        fi

        value=$second$sum$first
        echo $value
}
result=$(password_formula)
echo "The value is $result"

回答by Kat Farrell

It's due to the echostatements. You could switch your echos to prints and return with an echo. Below works

这是由于echo声明。您可以将回声切换为打印并返回echo. 下面的作品

#!/bin/bash

set -x
echo "enter: "
read input

function password_formula
{
        length=${#input}
        last_two=${input:length-2:length}
        first=`echo $last_two| sed -e 's/\(.\)/ /g'|awk '{print }'`
        second=`echo $last_two| sed -e 's/\(.\)/ /g'|awk '{print }'`
        let sum=$first+$second
        sum_len=${#sum}
        print $second
        print $sum

        if [ $sum -gt 9 ]
        then
           sum=${sum:1}
        fi

        value=$second$sum$first
        echo $value
}
result=$(password_formula)
echo $result

回答by Calpau

The answer above suggests changing the function to echo data rather than return it so that it can be captured.

上面的答案建议将函数更改为回显数据而不是返回它以便可以捕获它。

For a function or program that you can't modify where the return value needs to be saved to a variable (like test/[, which returns a 0/1 success value), echo $?within the command substitution:

对于无法修改返回值需要保存到变量的位置的函数或程序(如test/ [,它返回 0/1 成功值),请$?在命令替换中回显:

# Test if we're remote.
isRemote="$(test -z "$REMOTE_ADDR"; echo $?)"
# Or:
isRemote="$([ -z "$REMOTE_ADDR" ]; echo $?)"

# Additionally you may want to reverse the 0 (success) / 1 (error) values
# for your own sanity, using arithmetic expansion:
remoteAddrIsEmpty="$([ -z "$REMOTE_ADDR" ]; echo $((1-$?)))"

E.g.

例如

$ echo $REMOTE_ADDR

$ test -z "$REMOTE_ADDR"; echo $?
0
$ REMOTE_ADDR=127.0.0.1
$ test -z "$REMOTE_ADDR"; echo $?
1
$ retval="$(test -z "$REMOTE_ADDR"; echo $?)"; echo $retval
1
$ unset REMOTE_ADDR
$ retval="$(test -z "$REMOTE_ADDR"; echo $?)"; echo $retval
0

For a program which prints data but also has a return value to be saved, the return value would be captured separately from the output:

对于打印数据但还有要保存的返回值的程序,返回值将与输出分开捕获:

# Two different files, 1 and 2.
$ cat 1
1
$ cat 2
2
$ diffs="$(cmp 1 2)"
$ haveDiffs=$?
$ echo "Have differences? [$haveDiffs] Diffs: [$diffs]"
Have differences? [1] Diffs: [1 2 differ: char 1, line 1]
$ diffs="$(cmp 1 1)"
$ haveDiffs=$?
$ echo "Have differences? [$haveDiffs] Diffs: [$diffs]"
Have differences? [0] Diffs: []

# Or again, if you just want a success variable, reverse with arithmetic expansion:
$ cmp -s 1 2; filesAreIdentical=$((1-$?))
$ echo $filesAreIdentical
0

回答by Samuele Catuzzi

Simplest answer:

最简单的答案:

the return code from a function can be only a value in the range from 0 to 255 . To store this value in a variable you have to do like in this example:

函数的返回码只能是 0 到 255 范围内的值。要将这个值存储在一个变量中,你必须像在这个例子中那样做:

#!/bin/bash

function returnfunction {
    # example value between 0-255 to be returned 
    return 23
}

# note that the value has to be stored immediately after the function call :
returnfunction
myreturnvalue=$?

echo "myreturnvalue is "$myreturnvalue

回答by imal hasaranga perera

It is easy you need to echo the value you need to return and then capture it like below

您很容易需要回显您需要返回的值,然后像下面一样捕获它

demofunc(){
    local variable="hellow"
    echo $variable    
}

val=$(demofunc)
echo $val

回答by Ytsen de Boer

Use the special bash variable "$?" like so:

使用特殊的 bash 变量“$?” 像这样:

function_output=${my_function}
function_return_value=$?

回答by dinesh saini

Something like this could be used, and still maintaining meanings of return(to return control signals) and echo(to return information) and logging statements (to print debug/info messages).

可以使用这样的东西,并且仍然保持return返回控制信号)和echo返回信息)和日志语句(打印调试/信息消息)的含义。

v_verbose=1
v_verbose_f=""         # verbose file name
FLAG_BGPID=""

e_verbose() {
        if [[ $v_verbose -ge 0 ]]; then
                v_verbose_f=$(tempfile)
                tail -f $v_verbose_f &
                FLAG_BGPID="$!"
        fi
}

d_verbose() {
        if [[ x"$FLAG_BGPID" != "x" ]]; then
                kill $FLAG_BGPID > /dev/null
                FLAG_BGPID=""
                rm -f $v_verbose_f > /dev/null
        fi
}

init() {
        e_verbose

        trap cleanup SIGINT SIGQUIT SIGKILL SIGSTOP SIGTERM SIGHUP SIGTSTP
}

cleanup() {
        d_verbose
}

init

fun1() {
    echo "got " >> $v_verbose_f
    echo "got " >> $v_verbose_f
    echo "$((  +  ))"
    return 0
}

a=$(fun1 10 20)
if [[ $? -eq 0 ]]; then
    echo ">>sum: $a"
else
    echo "error: $?"
fi
cleanup

In here, I'm redirecting debug messages to separate file, that is watched by tail, and if there is any changes then printing the change, trapis used to make sure that background process always ends.

在这里,我将调试消息重定向到单独的文件,由尾部监视,如果有任何更改,则打印更改,trap用于确保后台进程始终结束。

This behavior can also be achieved using redirection to /dev/stderr, But difference can be seen at the time of piping output of one command to input of other command.

这种行为也可以使用重定向到 来实现/dev/stderr,但是在将一个命令的输出管道传输到另一个命令的输入时可以看到差异。