0

我有file1

#!/usr/bin/env bash
source $HOME/file2

answer=$(calculate)
echo "Answer is: $answer"

file2

#!/usr/bin/env bash

function calculate(){
    local result=$(echo $((RANDOM%2)))
    [ $result -gt 0 ] && exit 1
    echo "$result"  ## this line was missed and was just added
}

问题是calculate函数永远不会退出,即Answer is: 不管函数输出是什么,该行都会被打印出来。在两个文件或其中一个文件的顶部
插入set -u或也没有帮助。 我也试过让它退出使用,但仍然没有运气。set -eu
return 1

4

2 回答 2

2

如果你想捕获函数的输出,它必须在一个子shell中运行,这意味着你必须明确地检查调用者的退出状态,所以你最好只返回一个非零值。

calculate () {
    local result=$(( RANDOM % 2 ))
    [ "$result" -gt 0 ] || return 1
    echo "$result"
}

answer=$(calculate) || exit 1

此分配的退出状态是命令替换的退出状态。(严格来说,如果你不使用local, thenresult也会在命令替换的子shell中被定义为全局变量,而不是在你的脚本环境中。)


或者,您可以calculate设置一个全局变量,而不是将任何内容写入标准输出。

calculate () {
    answer=$(( RANDOM % 2 ))
    [ "$answer" -gt 0 ] || exit 1
}

calculate
echo "Answer = $answer"
于 2021-07-01T17:39:18.247 回答
0

这是一个使用退出代码但不调用退出的解决方案。

文件1:

#!/usr/bin/env bash
source $HOME/file2

calculate
echo "Answer is: $?"

请注意这里的实质性区别 - 我直接调用计算。我从计算中忽略了标准输出,而只是捕获了退出状态:$?。

和文件2:

#!/usr/bin/env bash

function calculate(){
    local result=$(echo $((RANDOM%2)))
     [ $result -gt 0 ] 
}

在 file2 中,calculate 返回的状态是最后执行的命令的状态。测试 ([]) 返回 0 表示真,1 表示假。因此,如果 $result 大于 0,将返回 0(这与您想要的相反)。想一想,这更像是您正在寻找的东西:

#!/usr/bin/env bash

function calculate(){
    local result=$(echo $((RANDOM%2)))
     ! [ $result -gt 0 ] 
}

calculate() 的最大变化是最后执行的命令的退出代码被用于生成函数的退出状态。如果您在直接调用的函数中使用 exit,exit 将立即终止您的调用 shell。

于 2021-07-01T18:06:32.897 回答