$? 사용에 대한 모범 사례 배쉬에서?

$? 사용에 대한 모범 사례 배쉬에서?

내가 이 글을 읽을 때대답$?또 다른 질문이 생겼습니다.

$를 사용하는 방법에 대한 모범 사례가 있나요? 배쉬에서?


예를 들어 보겠습니다.

우리는 선형 스크립트를 가지고 있으며 모든 명령이 올바르게 실행되는지 알고 싶습니다. 오류 코드를 확인하고 그렇지 않으면 중단하는 작은 함수("did_it_work"라고 함)를 호출할 수 있다고 생각합니다.

#!/bin/bash 

function did_it_work {
    code=$1
    if [ "$code" -ne "0" ]
    then
        echo "Error failure: code $code "
        exit 1
    fi
}

dir=some/path

mkdir -p $dir
did_it_work $? 

cd $dir
did_it_work $? 

run_some_command
did_it_work $? 

물론 이 접근 방식은 문제가 있는 경우 수동으로 수정하고 스크립트를 다시 실행해야 함을 의미합니다.

이것이 좋은 생각이라고 생각하시나요? 아니면 이를 수행하기 위한 다른 모범 사례가 있습니까?

/감사해요

답변1

일반적인 방법은 다음과 같습니다.

die() {
    IFS=' ' # make sure "$*" is joined with spaces

    # output the arguments if any on stderr:
    [ "$#" -eq 0 ] || printf '%s\n' "$*" 1>&2
    exit 1
}

그런 다음 다음과 같이 사용합니다.

mkdir -p some/path || die "mkdir failed with status $?"

또는 종료 상태를 포함하려면 다음과 같이 변경할 수 있습니다.

die() {
    last_exit_status=$?
    IFS=' '
    printf '%s\n' "FATAL ERROR: $* (status $last_exit_status)" 1>&2
    exit 1
}

그러면 다음을 사용하는 것이 더 쉬울 것입니다.

mkdir -p some/path || die "mkdir failed"

실패하면 mkdir오류 메시지가 표시될 수 있으므로 두 번째 메시지는 중복된 것으로 간주될 수 있습니다. 다음을 수행할 수 있습니다.

mkdir -p some/path || exit   # with the same (failing) exit status as mkdir's
mkdir -p some/path || exit 1 # with exit status 1 always

die(또는 인수 없이 위의 첫 번째 변형을 사용합니다 )

이전에 본 적이 없는 경우를 대비해 command1 || command2작동하며 , 실패 command1하더라도 작동합니다 .command1command2

그래서 "디렉토리를 만들지 않으면 죽는다"라고 읽을 수 있습니다.

귀하의 예는 다음과 같습니다

mkdir -p some/path || die "mkdir failed"
cd some/path || die "cd failed"
some_command || die "some_command failed"

또는 dies메인 코드가 더 잘 보이도록 오른쪽으로 더 정렬할 수도 있습니다.

mkdir -p some/path         || die "mkdir failed"
cd some/path               || die "cd failed"
some_command               || die "some_command failed"

또는 명령줄이 매우 긴 경우 다음 줄을 사용하세요.

mkdir -p some/path ||
  die "mkdir failed"

cd some/path ||
  die "cd failed"

some_command ||
  die "some_command failed"

또한 이름을 여러 번 사용하려는 경우 some/path이름을 변수에 저장하면 계속 입력할 필요가 없고 필요한 경우 쉽게 변경할 수 있습니다. 변수 인수를 명령에 전달할 때 --인수가 로 시작하면 옵션으로 간주되지 않도록 옵션 구분 기호를 사용해야 합니다 -.

dir=some/path
mkdir -p -- "$dir"         || die "Cannot make $dir"
cd -P -- "$dir"            || die "Cannot cd to $dir"
some_command               || die "Cannot run some_command"

답변2

다음과 같이 코드를 다시 작성할 수 있습니다.

#!/bin/bash
function try {
    "$@"
    code=$?
    if [ $code -ne 0 ]
    then
        echo "$1 did not work: exit status $code"
        exit 1
    fi
}

try mkdir -p some/path
try cd some/path
try run_some_command

실제로 오류 코드를 기록할 필요는 없지만 명령이 성공했는지 여부만 기록할 경우 try()다음과 같이 코드를 더욱 단축할 수 있습니다.

function try {
    if ! "$@"
    then
        echo "$1 did not work"
        exit 1
    fi
}

답변3

정말로 exit오류를 해결하고 Bash를 사용하고 있다면 From 도 고려해야 합니다 set -e.help set

-e 명령이 0이 아닌 상태로 종료되면 즉시 종료합니다.

이는 확실히 did_it_work() 함수의 유연성을 제공하지는 않지만 새 함수에 많은 호출을 추가하지 않고도 오류 발생 시 bash 스크립트가 중지되도록 하는 간단한 방법입니다.

관련 정보