Question: I want to assign my variable `a` a the first word of the result of the command `func <some_arg>` only if it does not fail. And if it fails I need to log that.

What I've done so far is:

```
func() {
    if [[ $1 -eq 1 ]]
    then
        echo 'hello world'
        return 0
    fi

    echo 'Something wrong has happened!' >> path/to/dev.log
    return 2
}

a=$(func 1)
r=$?

if [[ $r -eq 0 ]]
then
    a=$(awk '{ print $1 }' <<<"$a")
fi

```

This works of course but I do not like assigning my variable `a` twice.

I tried this:

```
  a=$(func 2 | awk '{ print $1 }') || echo 'Something wrong has happened!' >> path/to/dev.log

```

But it does not log anything

Is there a better way?

Answer: 
You could use `set -o pipefail` to get the error from the earlier part of the pipeline:

> 
> The return status of a pipeline is the exit status of the last command, unless the *pipefail* option is enabled. If *pipefail* is enabled, the pipeline's return
>  status is the value of the last (rightmost) command to exit with a non-zero status, or zero if all commands exit successfully. 
> 
> 
> 

```
$ foo() { [[ "$1" = 1 ]] || return 1; echo "hello world"; }
$ a=$(set -o pipefail; foo 2 | awk '{print $1}' || echo "fail..." >&2)
fail...

```

But really, I can't see why assigning twice would be an issue. In essence, you just modify the value you got if the command succeeds, or ignore it if it failed. 

Also, you can condense that logic a bit:

```
if a=$(foo 1); then
   a=${a%% *};
   echo "first word of a is '$a'"; 
   # do some work with $a...
else
   echo "error..." >&2;
fi

```

prints

```
first word of a is 'hello'

```
One issue with your code is that it clobbers `a` even if the function `func` returns a non-zero result.

Instead:

```
#!/bin/sh

func () {
    if [ "$1" -eq 1 ]; then
        echo 'some sort of logging stuff' >>logfile
        return 1
    fi

    echo 'hello world'
}

a="a string"

if b=$( func 0 ); then
    a=${b%% *}
fi

printf '1: a = "%s"\n' "$a"

a="a string"

if b=$( func 1 ); then
    a=${b%% *}
fi

printf '2: a = "%s"\n' "$a"

```

Running this will produce

```
1: a = "hello"
2: a = "a string"

```

As you can see, in the second case, `a` retains its value.