write to output stream and returning value from shell script function

眉间皱痕 提交于 2020-07-10 03:11:48

问题


In shell script, echo can be used to return values from functions. But, if those functions want to print some messages. Then, this can be done by redirecting it to error stream. Below is a simplified example :-

#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

Below is the sample execution output :-

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

That works fine. But when this script is used as a autosys job. then messages from logic functions ends up in error stream file triggering alerts.

Is there any way, messages from logic function can be written to output stream and not mixing messages with return value.


Edit 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 "$@"

Output :-

$

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

回答1:


Would this work?:

#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



回答2:


I'd suggest you use the return code if the return of the function is a simple state indicator (like ok or fail).

And since you tag your question as Bash, returning arbitrary values can be achieved by reference rather than using an output stream, with the advantage of not calling your function within sub-shell processes:

Passing return value as reference (result variable name passed as argument 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 "$@"

Alternatively you can use name-ref variables with declare -n and write the logic function as:

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

Another example with additional parameters used by 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 "$@"


来源:https://stackoverflow.com/questions/62738633/write-to-output-stream-and-returning-value-from-shell-script-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!