종료 코드를 반환하는 방법은 무엇입니까? 오류: 반환: 읽기: 숫자 인수가 필요합니다.

종료 코드를 반환하는 방법은 무엇입니까? 오류: 반환: 읽기: 숫자 인수가 필요합니다.

이것은 내 스크립트의 단순화된 버전입니다. 제 질문은 apt-get이 경우 종료 코드를 어떻게 반환할 수 있느냐는 것입니다.

#!/bin/bash
install_auto() {
apt-get -h > /dev/null 2>&1
if [ $? -eq 0 ] ; then
    return $(sudo apt-get install --assume-yes $@)
fi
return 1
}
echo "installing $@"
install_auto "$@"
echo $?
echo "finished"
exit 0

출력은 다음과 같습니다

./install_test.sh: line 5: return: Reading: numeric argument required

업데이트: 작동하는 것을 알아냈습니다.

return $(sudo apt-get install --assume-yes "$@" >/dev/null 2>&1; echo $?)

이것이 좋은 접근 방식입니까?

답변1

Bash는 return()숫자 매개변수만 반환할 수 있습니다. 어쨌든 기본적으로 마지막 명령 실행의 종료 상태를 반환합니다. 따라서 실제로 필요한 것은 다음과 같습니다.

#!/usr/bin/env bash
install_auto() {
apt-get -h > /dev/null 2>&1
if [ $? -eq 0 ] ; then
    sudo apt-get install --assume-yes $@
fi
}

함수가 기본적으로 반환하므로 반환할 값을 명시적으로 설정할 필요가 없습니다 $?. 그러나 첫 번째 명령이 실패하고 루프를 입력하지 않으면 apt작동하지 않습니다 if. 더욱 강력하게 만들려면 다음을 사용하세요.

#!/usr/bin/env bash
install_auto() {
apt-get -h > /dev/null 2>&1
ret=$?
if [ $ret -eq 0 ] ; then
    ## If this is executed, the else is ignored and $? will be
    ## returned. Here, $?will be the exit status of this command
    sudo apt-get install --assume-yes $@
else
    ## Else, return the exit value of the first apt-get
    return $ret
fi
}

일반적인 규칙은 함수가 반드시 마지막으로 실행한 작업이 아닌 특정 작업의 종료 상태를 반환하려면 종료 상태를 변수에 저장하고 해당 변수를 반환해야 한다는 것입니다.

function foo() {
    run_a_command arg1 arg2 argN
    ## Save the command's exit status into a variable
    return_value= $?

    [the rest of the function  goes here]
    ## return the variable
    return $return_value
}

편집: 실제로 @gniourf_gniourf가 의견에서 지적했듯이 다음을 사용하여 모든 것을 크게 단순화할 수 있습니다 &&.

install_auto() {
  apt-get -h > /dev/null 2>&1 &&
  sudo apt-get install --assume-yes $@
}

이 함수의 반환 값은 다음 중 하나입니다.

  1. 실패 하면 apt-get -h 종료 코드를 반환합니다.
  2. 성공 하면 apt-get -h종료 코드가 반환됩니다 sudo apt-get install.

답변2

완전성을 기하기 위해 @terdon 및 @gniourf_gniourf가 제안한 대로 몇 가지 수정 사항을 적용한 실제 기능은 다음과 같습니다.

install_auto() {
    if [ ! $# -gt 0 ] ; then
        echo "usage: $0 package_name [package_name ...]"
    fi 

    apt-get -h > /dev/null 2>&1
    if [ $? -eq 0 ] ; then
        if [ -f "$@" ] || [[ "$@" =~ '/' ]] ; then
            sudo gdebi -n "$@"
            return $?
        else    
            sudo apt-get install --assume-yes "$@"
            return $?
        fi
    fi

    zypper help > /dev/null 2>&1
    if [ $? -eq 0 ] ; then
            sudo zypper --non-interactive --no-gpg-checks --quiet install --auto-agree-with-licenses "$@"
            return $?
    fi

    #may check other package managers in the future

    echo "ERROR: package manager not found"
    return 255
}

추가 조언을 주시면 감사하겠습니다.

관련 정보