bash 스크립트의 인수를 스크립트의 함수로 전달

bash 스크립트의 인수를 스크립트의 함수로 전달

내 스크립트:

#! /bin/bash --

set -x

## docker-compose wrapper
compose_fn() {
  local ENV="${1}"
  local VERB="${2}"
  local SERVICE="${3}"
  local CMD="docker-compose -f ${ENV}.yml"
  case "${VERB}" in
    (exec)
      shift "$#" # remove args passed to this fn
      # Execute a command in a running container.
      if [ -n "${SERVICE}" ]; then
        ${CMD} "${VERB}" "${SERVICE}" "$@"
      else
        echo "## Err: You must specify service name..."
        exit 1
      fi
    ;;
  esac
}

compose_fn "${1}" "${2}" "${3}"

다음 오류로 인해 어려움을 겪고 있습니다.

$ ./tst.sh dev exec django sh
+ compose_fn dev exec django
+ local ENV=dev
+ local VERB=exec
+ local SERVICE=django
+ local 'CMD=docker-compose -f dev.yml'
+ case "${VERB}" in
+ shift 3
+ '[' -n django ']'
+ docker-compose -f dev.yml exec django
Execute a command in a running container

Usage: exec [options] [-e KEY=VAL...] SERVICE COMMAND [ARGS...]

Options:
....

내 실수는 어디에 있습니까? 어떻게 하면 더 잘할 수 있을까요?

내가 아는 한, 4개의 매개변수를 [dev, exec, django, sh]스크립트에 전달한 다음 그 중 3개( shift 3)를 스크립트에서 제거하여 var sh에 남아 있도록 했습니다 .$@

답변1

shift "$#"당신 과 함께 $@완전히 비어 있습니다 . $@함수에 있는 것들은 기본 스크립트에 있는 것과 별개입니다 $@. $@함수에서 사용하고 닫아야 하는 스크립트 요소 수를 정확히 알고 있으므로 그냥 전달하는 것이 좋습니다.모두함수의 매개변수를 삭제하고 처음 세 개를 제거하시겠습니까?

#! /bin/bash --

set -x

## docker-compose wrapper
compose_fn() {
  local env="$1"
  local verb="$2"
  local service="$3"

  local cmd=( docker-compose -f "$env.yml" )

  shift 3 # we've now used up three arguments

  case $verb in
      exec)
          # Execute a command in a running container.
          if [ -n "$service" ]; then
              "${cmd[@]}" "$verb" "$service" "$@"
          else
              echo '## Err: You must specify service name...' >&2
              exit 1
          fi
          ;;
      *)
          printf 'Unknown verb: %s\n' "$verb" >&2
          exit 1
    esac
}

compose_fn "$@"

ENV또한 실수로 시스템 변수나 특수 쉘 변수( 예: 일부 쉘이 특정 상황에서 사용하는 변수) 를 사용하지 않도록 변수 이름을 소문자로 사용했고 불필요한 따옴표와 중괄호를 모두 제거했습니다.

또한 YAML 파일 이름을 올바르게 참조할 수 있도록 명령을 배열에 넣었습니다.

스크립트의 나머지 부분이 어떻게 보이는지, 그리고 그것이 의미가 있는지에 따라 함수 외부로 세 가지 변수에 대한 설정을 이동할 수도 있습니다. 이 세 변수는 스크립트에서 전역 변수가 됩니다.

#! /bin/bash --

set -x

## docker-compose wrapper
compose_fn() {
  local cmd=( docker-compose -f "$env.yml" )

  case $verb in
      exec)
          # Execute a command in a running container.
          if [ -n "$service" ]; then
              "${cmd[@]}" "$verb" "$service" "$@"
          else
              echo '## Err: You must specify service name...' >&2
              exit 1
          fi
          ;;
      *)
          printf 'Unknown verb: %s\n' "$verb" >&2
          exit 1
    esac
}

env="$1"
verb="$2"
service="$3"

shift 3

compose_fn "$@"

[ -n "$service" ]테스트를 우회할 수도 있습니다.

service=${3:?'## Err: You must specify service name...'}

매개변수 확장은 설정 되지 않았거나 빈 정의 라는 ${parameter:?word}메시지와 함께 쉘을 종료합니다 . 쉘은 다음과 같이 형식을 지정합니다.wordparameterbash

script.sh: line 9: 3: ## Err: You must specify service name...

관련된:

관련 정보