argsで呼び出された関数の中からファイル引数を取得する

argsで呼び出された関数の中からファイル引数を取得する

状況は次のとおりです。関数と次のような他のコマンドを含むシェルスクリプトファイルがあります。

#!/bin/sh

myFunc() {
  for arg in "$@"; do
    # ... do something with every arg passed to myFunc
  done
}

# ... do something

myFunc func-arg-1

# ... do something

myFunc func-arg-2 func-arg-1

# ... do something

内からファイルにパラメータを渡すことは可能ですかmyFunc

答え1

Bash / Ksh / Zshにアクセスできる場合は、スクリプトの引数を配列に入れて関数内でアクセスできます。

#!/bin/bash
args=( "$@" )
func() {
    local x
    for x in "$@"; do
        echo "$x is an argument to the function"
    done
    for x in "${args[@]}"; do
        echo "$x is an argument to the script"
    done
}
func bla

POSIX シェルには単一引数リスト以外に配列はありません。スクリプト引数と関数引数を区別する必要がある場合は、一部の区切り文字を使用してスクリプト引数を関数に手動で渡すことができます。

#!/bin/sh
delim=:::
func() {
    delim_seen=0
    for k in "$@"; do
        if [ "$k" = "$delim" ]; then
            delim_seen=1
            continue;
        elif [ "$delim_seen" = 0 ]; then
            echo "$k is an argument to the function only"
        else
            echo "$k is an argument to the script"
        fi
    done
}
func bla "$delim" "$@"

もちろん、実際のパラメータ自体に区切り文字列が含まれていると、これは失敗します。数を明示的に渡すためのStéphaneのソリューションもちろん、このような問題がないので、より良いです。

ただし、どの方法を使用してもパラメータへのランダムアクセスはほとんど不可能です。これは、各リストが順次処理されても、両方のリストを同時に処理する場合にも当てはまります。これを行う必要がある場合は、機能が豊富なシェルまたは実際のプログラミング言語(Perl、Pythonなど)に切り替えることをお勧めします。


スクリプトがオプションのスイッチである引数(たとえば-i、または-k foo)を使用している場合は、getopts関数を呼び出す前に別の変数に解析できます。または、関数のパラメータがスイッチに似ている場合は、別の変数に入れます。

そして、関数の引数に既知の構造があり、任意のファイル名ではなく「良い」文字列と見なされる場合は、単一の文字列で囲むことができます。それ自体。次に、パターンマッチングとパラメータ拡張を適用してバッチを処理します。 (または空が禁止され、意図的に噴射を呼び出す場合もあります。) きれいではありませんが、実行可能であり、詳細によって大きく異なります。

答え2

関数内では、sh位置引数($1$2...、、、$@$*は関数自体の位置引数であり、スクリプトの位置引数(または他の関数から呼び出された場合は親関数の位置引数)にアクセスできなくなります。

したがって、これらのパラメータを他の方法で関数に渡す必要があります。

配列変数がサポートされていないことは役に立ちません。shこれにより、ランダムな文字列のリストを保存するのが難しくなります。

他の人がすでに提案したソリューションに加えて、次のこともできます。

#! /bin/sh -

myFunc() {
  n="$(( $# - $1 - 1 ))" i=0; shift
  for arg do
    case "$i" in
      ("$n") break;;
      (0) shift "$n";; # on first pass, remove the function arguments from "$@"
    esac
    i="$(( i + 1 ))"
    # ... do something with every "$arg" passed to myFunc and with "$@"
  done
}

次のように呼び出されますmyFunc

myFunc "$#" args for myFunc "$@"

答え3

ただ関数に渡してください。

myFunc func-arg-2 func-arg-1 "$@"

関連情報