【问题标题】:write to output stream and returning value from shell script function写入输出流并从 shell 脚本函数返回值
【发布时间】:2020-07-05 08:47:34
【问题描述】:

在 shell 脚本中,echo 可用于从函数返回值。 但是,如果这些函数想要打印一些消息。 然后,这可以通过将其重定向到错误流来完成。 下面是一个简化的例子:-

#this is a function that returns a value, as well as
#print some messages
function logic(){
    echo >&2 "start of logic"
    echo >&2 "perform logic, to get value"

    echo "ok"
}

function smain(){
    local result=$(logic)

    echo "result is >$result<"

    if [ "$result" == "ok" ];then
        echo "script successful"
    else
        echo "script failed"
    fi
}

smain

以下是示例执行输出:-

sh sample.sh
start of logic
perform logic, to get value
result is >ok<
script successful

效果很好。 但是当此脚本用作 autosys 作业时。 然后来自逻辑函数的消息最终会出现在触发警报的错误流文件中。

有什么办法,可以将来自逻辑函数的消息写入输出流,而不是将消息与返回值混合。


编辑 1:-

#!/usr/bin/env bash

function Return(){
    printf -v "$1" '%s' '$*'
}

function logic() {
    local arg=$1
    local system=$2
    echo "start of logic"
    echo "all params are >$*<"
    echo "perform logic, to get value"
    echo >&2 "logic successfully completed"
    printf -v "$1" '%s' 'abraKaDabra'
}

function main() {
    local result='' ;  logic "$@" result

    printf 'result is >%s<\n' "$result"

    if [ "$result" = "ok" ]; then
        echo "script successful"
    else
        echo "script failed"
    fi

    echo >&2 "end of main"
}

main "$@"

输出:-

$

sh returnValueWithDebugging.sh abc xyz > out.log 2>err.log

$

cat err.log
logic successfully completed
end of main

$

cat out.log
start of logic
all params are >abc xyz result<
perform logic, to get value
result is ><
script failed

【问题讨论】:

  • 您可以使用smain 2&gt;&amp;1 将标准错误重定向到标准输出。这就是你要问的吗?不熟悉 AutoSys。
  • 我做不到。因为这会将错误消息也重定向到输出流。
  • 改为记录到文件?

标签: bash shell stdout stderr autosys


【解决方案1】:

这行得通吗?:

#this is a function that returns a value, as well as                            
#print some messages                                                            
function logic(){
    echo "start of logic"
    echo "perform logic, to get value"

    echo "ok" >&2
}

function smain(){
    { local result=$( { { logic ; } 1>&3 ; } 2>&1); } 3>&1

    echo "result is >$result<"

    if [ "$result" == "ok" ];then
        echo "script successful"
    else
        echo "script failed"
    fi
}

smain

【讨论】:

  • 请您解释一下,{ local result=$( { { logic ; } 1>&3 ; } 2>&1); 中发生了什么3>&1
  • 明白了,您正在交换标准错误和标准输出流
  • 但看不懂括号
  • logic() 中返回的值被写入标准错误(我猜你可以使用&gt;&amp;4 并留下标准错误,没有尝试)。 {}s 只是重定向流时的语法,首先1&gt;&amp;3 使用&amp;3 作为临时,然后将stderr 重定向到stdout 以获取返回值到$result,最后3&gt;&amp;1 返回到stdout 以进行正常输出.
  • 您好 James,发布了一个后续问题。 stackoverflow.com/questions/62739537/…。谢谢
【解决方案2】:

如果函数的返回是一个简单的状态指示符(如正常或失败),我建议您使用返回码。

由于您将问题标记为 Bash,因此可以通过引用而不是使用输出流来返回任意值,其优点是不在子 shell 进程中调用您的函数:

将返回值作为引用传递(结果变量名作为参数 1 传递):

#!/usr/bin/env bash
logic()
{
  echo "start of logic"
  echo "perform logic, to get value"
  printf -v "$1" '%s' 'ok'
}

function main ()
{
  result=''
  logic result

  printf 'result is >%s<\n' "$result"

  if [ "$result" = "ok" ];then
    echo "script successful"
  else
    echo "script failed"
  fi
}

main "$@"

或者,您可以将 name-ref 变量与 declare -n 一起使用,并将 logic 函数编写为:

logic()
{
  local -n res="$1"
  echo "start of logic"
  echo "perform logic, to get value"
  res='ok'
}

logic 使用的附加参数的另一个示例:

#!/usr/bin/env bash
logic()
{
  local -n res="$1"
  local a="$2"
  local b="$3"
  echo "start of logic"
  echo "perform logic, to get value"
  if [ $a -gt $b ]; then
    res='ok'
  else
    res='oh no!'
  fi
}

function main ()
{
  result=''
  logic result 3 2

  printf 'result is >%s<\n' "$result"

  if [ "$result" = "ok" ];then
    echo "script successful"
  else
    echo "script failed"
  fi

  logic result 5 10

  printf 'result is >%s<\n' "$result"
}

main "$@"

【讨论】:

  • 如果逻辑需要一些参数来执行
  • @mogli 如果logic 需要其他参数,则使用其他参数。
  • 谢谢。我按照建议尝试了。更新了 Edit1 下的帖子。但是,结果是空的
  • 我的错,我在结果之前添加了 args。谢谢
  • 实际需求是在子shell进程中调用逻辑。这样父 shell 进程就不会受到子 shell 进程变量和导出的污染。有什么办法吗?
猜你喜欢
  • 2017-10-02
  • 1970-01-01
  • 1970-01-01
  • 2013-07-16
  • 2016-03-14
  • 1970-01-01
  • 1970-01-01
  • 2022-10-23
  • 2014-05-25
相关资源
最近更新 更多