0

As a part of my script, I want to publish package to nuget feed:

dotnet nuget push package.1.2.3.nupkg --source "mysource" --api-key "mykey"

The command may print error: 409 already contains version 1.2.3 and exit with code 1. This is perfectly fine in my context, but it makes the whole script fail. I want to wrap this command with something, that will swallow non-zero exit code if specific error appears in stdout, but to bubble up non-zero exit code if it does not appear. What can I use for my task?

8
  • 2
    What pipeline? How does it fail? … … … … … … … … … … … … … … … Please do not respond in comments; edit your question to make it clearer and more complete. Commented Apr 28, 2019 at 16:14
  • @Scott I just replaced CI pipeline with script to be more general, is that fine to you? Commented Apr 28, 2019 at 16:21
  • 1
    My point is that a non-zero exit code doesn’t cause a whole script to fail unless you have done set -e (or you are testing the code and explicitly exiting). So, no, you haven’t really answered my question “How does it fail?” Commented Apr 28, 2019 at 17:05
  • 1
    Is it the combination of the output and the exit status=1 that you need, or can you ignore every exit status of 1?
    – Jeff Schaller
    Commented Apr 28, 2019 at 17:12
  • @JeffSchaller I did not check error code on other cases when error happens, but I can assume that it is always 1, so I have to handle code 1 in combination with this specific output/ Commented Apr 28, 2019 at 17:14

3 Answers 3

3

This script catches stdout and stderr and prints it to stdout again if exit code is 0 and to stderr otherwise.

If the string contains "error: 409 already contains version", then the function returns 0 and the original exit code otherwise.

#!/bin/bash

function do_nuget ()
{
        # save stdout and stderr
        out=$(dotnet nuget push "$1" --source "$2" --api-key "$3" 2>&1)
        exitcode=$?

        # if out is not empty...
        if [ -n "$out" ]; then
                if [ $exitcode -eq 0 ]; then
                        # echo to stdout
                        echo "$out"
                else
                        # echo to stderr
                        echo "$out" >&2
                fi
        fi
        if [ "$out" != "${out/error: 409 already contains version}" ]; then
                return 0
        fi
        return $exitcode
}
do_nuget "package.1.2.3.nupkg" "mysource" "mykey"
echo "got exit code: $?"
1

Are you after something more complicated than this?

emsg=$(your_command ... 2>&1) ||
    case $emsg in
    *"ignorable error condition"*) ;; # do nothing
    *) printf >&2 '%s\n' "$emsg"; exit 1 ;;
    esac

As a function:

# usage ignore pattern cmd [args ...]
ignore(){(
    pat=$1; shift; exec 3>&1
    emsg=$("$@" 2>&1 >&3 3>&-) || { e=$? &&
        case $emsg in
        $pat) ;; # ignore
        *) printf >&2 '%s\n' "$emsg"; exit "$e" ;;
        esac
    }
)}

You'll have to get rid of the extra fd juggling if your program is writing its error: 409 .. message to stdout, not to stderr.

0

You could add || true to the line in your script i.e.

dotnet nuget push package.1.2.3.nupkg --source "mysource" --api-key "mykey" || true

as suggested by this answer on Stackoverflow

2
  • 3
    yeah, but i think it will swallow every error, instead of just the single one I want swallowed, isn't it? Commented Apr 28, 2019 at 17:11
  • 1
    You are right, I mistakenly thought you wanted the script to continue regardless of which error happened.
    – AcId
    Commented Apr 28, 2019 at 17:21

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .