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 "$@"

관련 정보