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)をスクリプトから削除してvarshに残しました。$@

ベストアンサー1

shift "$#"あなたと$@完全に空です。$@関数内のものは基本スクリプトのものとは別です$@$@関数が使用して閉じる必要があるスクリプト要素の数を正確に知っているので、単に渡すことをお勧めします。みんな関数のパラメータを削除して最初の3つを削除しますか?

#! /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ファイル名を正しく参照できるように、コマンドを配列に入れました。

スクリプトの残りの部分がどのように見えるか、それが意味があるかどうかに応じて、関数の外に3つの変数の設定を移動することもできます。これら3つの変数はスクリプト内のグローバル変数になります。

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

関連:

おすすめ記事