子 shell 如何返回变量(而不是文件)中的数据并同时输出不同的日志?

子 shell 如何返回变量(而不是文件)中的数据并同时输出不同的日志?

假设我有以下 JavaScript:

    const something = doSomething();
    
    function doSomething() {
        console.log("About to do something");
        
        const a = doSomethingElse();
        if (a == "dog") {
            console.log("Worked");
            console.log("Now let's do xyz");
            return "cat";
        } else {
            console.log("failed for some reason");
            return "horse";
        }
    }
    
    function doSomethingElse() {
        console.log("About to do more");
        console.log("Done doing more stuff");
        
        return "dog";
    }

我们如何在 bash 中实现这一目标?我想实时查看日志,而不是将它们存储在文件中供以后使用?我正在考虑类似以下的内容,但随后所有内容都混合在一起,再加上 bash 中的 return 关键字有其他用途并且不能接受字符串。

    something=$(doSomething);
    
    function doSomething() {
        console_log "About to do something";
        
        a=$(doSomethingElse);
        if [[$a = "dog"]]; then
            console_log "Worked";
            console_log "Now let's do xyz";
            echo "cat"; # Wish I could do return "cat" ...
        else
            console_log "failed for some reason";
            echo "horse"; # Wish I could do return "horse" ...
        fi;
    }
    
    function doSomethingElse() {
        console_log "About to do more";
        console_log "Done doing more stuff";
        
        echo 'dog'; #Wish I could do return "dog" ...
    }
    
    function console_log() {
        #Is echo the right thing, or tee, or something else ?
        echo $1;
    }

不是有多个输出流来实现这一点吗?或者,是否有 $() 的替代方法来分配变量?我尝试过玩 T 恤、&*、&?和 3>1 的东西,我无法理解这一切......:(

我在 CentOS 7.9 下有 bash 4.2.46

感谢您的帮助 :)

答案1

这应该没问题:

#! /bin/bash -

doSomething() {
    print_err "About to do something"

    a="$(doSomethingElse)"
    if [[ "$a" = "dog" ]]; then
        print_err "Worked"
        print_err "Now let's do xyz"
        printf '%s' "cat"
    else
        print_err "failed for some reason"
        printf '%s' "horse"
    fi
}

doSomethingElse() {
    print_err "About to do more";
    print_err "Done doing more stuff";
    printf '%s' 'dog'
}

print_err() {
    # Print to stderr as we do this in functions
    # that print result to stdout
    printf '%s\n' "$1" >&2
}

something="$(doSomething)"
# Making it readonly would be somewhat similar to const
readonly something

printf '%s\n' "$something"

需要:

一般来说:

除此之外,替换[[[将使其sh符合要求。“sh 兼容”是什么意思?

还要查看变量的范围。有没有办法让本地命令可移植到 dash ksh bash 和 zsh?

就像在,你可以有, 完毕:

set_something() {
    something='cat'
}

set_something
printf 'something="%s"\n' "$something"

JavaScript 不能处理流,而 shell 可以。简化一下:

  • readfrom stdin,文件描述符0(标准)
  • writeto stdout,文件描述符1(标准输出)
  • writeto stderr,文件描述符2(标准错误)

除此之外,还可以打开新文件、读/写文件等。

可能感兴趣/dev/stdin、/dev/stdout 和 /dev/stderr 的可移植性如何?


返回值。

Bash 函数不会“返回”字符串。当一个人这样做时:

foo="$(some command)"

some command将的标准输出分配给foo。如果不更改重定向非数据在您的代码中打印,您可以通过以下方式查看:

# In doSomething():
    printf 'a="%s"\n' "$a" >&2

# At end:
printf '"%s"\n' "$something"

你会得到:

a="About to do more
Done doing more stuff
dog"
something="About to do something
failed for some reason
horse"

如您所见,整个输出都已分配。

“使固定”可以通过将 stderr 重定向到 stdout 来捕获两者stdoutstderr

foo="$(some command 2>&1)"

退出代码

然而,Shell 函数确实有退出代码,就像任何程序一样。如果没有显式返回值,则它是该函数中执行的最后一个命令的退出状态。0没问题,其他任何事情都被认为是测试中的错误。

简单的例子:

#! /bin/bash -

foo() {
    printf 'I am foo\n'
    return 1
}
greetings() {
    if [ "$1" = "hi" ]; then
        printf 'Hello\n'
    else
        printf 'I do not know what to do with %s\n' "$1"
        return 12
    fi
}
if foo; then
    printf 'OK\n'
else
    printf 'FAIL\n'
fi

printf '\n## Try greetings "yo":\n'
greetings yo
ecode=$?
printf 'greetings() returned %d\n' "$ecode"

printf '\n## Try greetings "hi":\n'
greetings hi
ecode=$?
printf 'greetings() returned %d\n' "$ecode"

结果:

I am foo
FAIL

## Try greetings "yo":
I do not know what to do with yo
greetings() returned 12

## Try greetings "hi":
Hello
greetings() returned 0

一些帮助shellcheck

虽然不是万无一失,但对检查脚本有很大帮助。

您可以将它用作命令行工具,在线粘贴代码,或将其合并到您的编辑器中。

例如,如果您将 Vim 与 A​​LE 一起使用,则shellcheck如果已安装,它就会启动。但请注意,与发行版捆绑在一起的软件包可能有些过时。以Ubuntu 18.04为例,使用v0.4.6

https://github.com/koalaman/shellcheck

一般 Shell 脚本

和等人一起玩bash。对学习有用。永远考虑你想做什么。例如,使用其他工具进行文本处理几乎总是效果更好。然后可以使用 shell 脚本将它们粘合在一起。使用管道等 - unices 的一部分功能。这里例如sort,,,,,,,,,,,,,,,,,,,,,,,,等等。​​​​​​​​​​​​​joincuttrpasteuniqfindgrepcatdatetailheadxargswcfoldcolumnpaste

交互式 shell 脚本不仅可以使用它,还可以使用各种功能扩展您的 shell。

对于更高级的数据类型和复杂性,可以使用perlpython、 以及其他各种类型,甚至c.c一般来说,这是一种在较低级别了解系统的非常好的方法。

awksed对于处理文本也非常强大和有用,更awk容易学习。

相关内容