성공할 경우 파이프된 명령의 결과를 할당합니다.

성공할 경우 파이프된 명령의 결과를 할당합니다.

명령이 실패하지 않은 경우에만 a명령 결과의 첫 번째 단어를 내 변수에 할당하고 싶습니다. func <some_arg>실패하면 문서화해야 합니다.

지금까지 내가 한 일은 다음과 같습니다.

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

이것은 확실히 작동하지만 변수를 두 번 할당하는 것을 좋아하지 않습니다 a.

나는 이것을 시도했습니다 :

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

하지만 아무것도 기록하지 않습니다

더 좋은 방법이 있나요?

답변1

set -o pipefail다음을 사용하여 파이프라인의 이전 부분에서 오류를 얻을 수 있습니다 .

파이프의 반환 상태는 마지막 명령의 종료 상태입니다.파이프 고장옵션이 활성화되었습니다. 만약에파이프 고장활성화되면 파이프의 반환 상태는 0이 아닌 상태로 종료된 마지막(가장 오른쪽) 명령의 값이거나 모든 명령이 성공적으로 종료된 경우 0입니다.

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

하지만 실제로는 왜 두 번 할당하는 것이 문제가 되는지 이해가 되지 않습니다. 기본적으로 명령이 성공하면 얻은 값을 수정하고 명령이 실패하면 무시합니다.

또는 해당 논리를 약간 압축할 수 있습니다.

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

인쇄

first word of a is 'hello'

답변2

셸에는 문자열의 첫 번째 단어를 구문 분석하는 몇 가지 기본 메서드가 있습니다.

  1. 접미사로 다듬기 -${a%% *}

  2. 위치 인수에 할당 - set -- ${a}결과는 에 있습니다 $1. 를 사용하여 이를 단순화할 수 있습니다 set -- $(func 1).

  3. bash(만) 배열 요소로 나누기 - a=( $(func 1) )- 결과는 에 있습니다 ${a[0]}.

답변3

a코드의 한 가지 문제는 함수가 func0이 아닌 결과를 반환하더라도 충돌이 발생한다는 것입니다.

대신에:

#!/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"

이것을 실행하면

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

보시다시피 두 번째 경우에는 a해당 값이 유지됩니다.

관련 정보