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

2024-11-12 08:36:00
admin
原创
173
摘要:问题描述:我知道 Linux 中的一些非常基本的命令,并且正在尝试编写一些脚本。我编写了一个函数,用于计算一个 5 位数字中最后 2 位数字的总和。该函数应将这个结果总和连接到最后 2 位数字之间并返回它。我想要返回这个值的原因是我将在另一个函数中使用该值。例如:如果我有 12345,那么我的函数将计算 4 ...

问题描述:

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

例如:如果我有 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 $2}'`
        second=`echo $last_two| sed -e 's/(.)/ /g'|awk '{print $1}'`
        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

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

-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 $2}'
+++ first=5
++++ echo 85
++++ sed -e 's/(.)/ /g'
++++ awk '{print $1}'
+++ 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

我还尝试将结果打印为:

password_formula
RESULT=$?
echo $RESULT

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

++ RESULT=67
++ echo 67
67

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


解决方案 1:

最简单的答案:

函数的返回代码只能是 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

解决方案 2:

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

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

echo "$value"

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

echo "my irrelevant info" >&2 

最后,为了捕捉它,使用你所做的:

 result=$(password_formula)

换句话说:

echo "enter: "
        read input

password_formula()
{
        length=${#input}
        last_two=${input:length-2:length}
        first=`echo $last_two| sed -e 's/(.)/ /g'|awk '{print $2}'`
        second=`echo $last_two| sed -e 's/(.)/ /g'|awk '{print $1}'`
        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"

解决方案 3:

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

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

val=$(demofunc)
echo $val

解决方案 4:

使用特殊 bash 变量“$?”如下:

function_output=$(my_function)
function_return_value=$?

解决方案 5:

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

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

# 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-$?)))"

例如

$ 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

对于打印数据但也有返回值需要保存的程序,返回值将从输出中单独捕获:

# 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

解决方案 6:

这是由于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 $2}'`
        second=`echo $last_two| sed -e 's/(.)/ /g'|awk '{print $1}'`
        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

解决方案 7:

可以使用类似的东西,并且仍然保持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 $1" >> $v_verbose_f
    echo "got $2" >> $v_verbose_f
    echo "$(( $1 + $2 ))"
    return 0
}

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

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

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

解决方案 8:

好的,如果我们设置了,那么这个问题的主要答案是有问题的errexit,例如

#!/bin/bash
set -o errexit

my_fun() {
    # returns 0 if the first arguments is "a"
    # 1 otherwise
    [ "${1}" = "a" ]
}

my_fun "a"
echo "a=$?"
my_fun "b"
echo "b=$?"

在这种情况下,当结果不是 0 时,bash 就会退出,例如,这只会打印一行。

./test_output.sh 
a=0

正如已经说过的,这里可能最正确的答案是这样的:

# like this
my_val=0 ; my_fun "a" || my_val=$?
echo "a=${my_val}"

# or this
my_fun "b" && my_val=0 || my_val=$?
echo "b=${my_val}"

这将正确打印所有值,且无错误

a=0
b=1

我不知道“echo”实现是否最正确,因为我仍然不清楚 $() 是否创建了子 shell。例如,我有一个函数,它在函数中打开一个文件描述符并返回数字,似乎 bash 在退出该函数后关闭了 fd。(如果有人能在这里帮助我 :-)

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用