programing

어레이를 bash 매개 변수로 전달

batch 2023. 4. 11. 21:50
반응형

어레이를 bash 매개 변수로 전달

배열을 매개 변수로 bash 함수에 전달하려면 어떻게 해야 합니까?

주의: Stack Overflow에서 답을 찾지 못한 후, 제가 직접 다소 조잡한 해결책을 올렸습니다.매개 변수 목록의 마지막 요소가 되는 배열을 하나만 전달할 수 있습니다.실제로는 어레이를 전혀 통과시키지 않고 요소의 목록을 전달하고 있습니다.이 목록은 에 의해 어레이로 재구성됩니다.called_function() 있는 이 있다면 .만약 누군가가 더 나은 방법을 알고 있다면, 여기에 그것을 추가해 주세요.

다음과 같은 방법으로 여러 어레이를 인수로 전달할 수 있습니다.

takes_ary_as_arg()
{
    declare -a argAry1=("${!1}")
    echo "${argAry1[@]}"

    declare -a argAry2=("${!2}")
    echo "${argAry2[@]}"
}
try_with_local_arys()
{
    # array variables could have local scope
    local descTable=(
        "sli4-iread"
        "sli4-iwrite"
        "sli3-iread"
        "sli3-iwrite"
    )
    local optsTable=(
        "--msix  --iread"
        "--msix  --iwrite"
        "--msi   --iread"
        "--msi   --iwrite"
    )
    takes_ary_as_arg descTable[@] optsTable[@]
}
try_with_local_arys

에코:

sli4-iread sli4-iwrite sli3-iread sli3-iwrite  
--msix  --iread --msix  --iwrite --msi   --iread --msi   --iwrite

편집/메모: (아래 설명에서)

  • descTable ★★★★★★★★★★★★★★★★★」optsTable이름으로 전달되고 함수에서 확장됩니다.에, 「」는 없습니다.$매개 변수로 지정될 때 필요합니다.
  • 은, 「아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아, 아,descTable는 「」로 .local왜냐하면 지역 주민들은 그들이 부르는 기능을 볼 수 있기 때문이다.
  • !${!1} 1 를 확장합니다
  • declare -a는 인덱스 배열을 명확하게 할 뿐, 엄밀하게는 필요 없습니다.

주의: Stack Overflow에서 답을 찾지 못한 후 제가 직접 올린 다소 조잡한 해결책입니다.매개 변수 목록의 마지막 요소가 되는 배열을 하나만 전달할 수 있습니다.실제로는 배열을 전혀 통과하지 않고 called_function()에 의해 배열로 재구성된 요소의 리스트입니다만, 나에게는 효과가 있었습니다.조금 후에 켄은 그의 해결책을 올렸지만, 저는 "역사적인" 참조를 위해 여기에 제 해결책을 보관했습니다.

calling_function()
{
    variable="a"
    array=( "x", "y", "z" )
    called_function "${variable}" "${array[@]}"
}

called_function()
{
    local_variable="${1}"
    shift
    local_array=("${@}")
}

Ken Bertelson 솔루션에 대한 코멘트와 Jan Hettich 답변:

구조

takes_ary_as_arg descTable[@] optsTable[@]을 서다try_with_local_arys()다음 중 하나:

  1. 이은, , this, this의 of of of of of 、 this 、 피 、 this 、 this 、 this this this 。descTable ★★★★★★★★★★★★★★★★★」optsTable takes_ary_as_arg★★★★★★ 。
  2. takes_ary_as_arg()가 수신하다descTable[@] ★★★★★★★★★★★★★★★★★」optsTable[@]으로서, 즉 '문자열', '문자열을 의미합니다.$1 == descTable[@] ★★★★★★★★★★★★★★★★★」$2 == optsTable[@].
  3. 의의 intakes_ary_as_arg()${!parameter}구문(간접 참조 또는 이중 참조라고도 함)은 의 값을 사용하는 대신확장값을 사용하는 것을 의미합니다.예:

    baba=booba
    variable=baba
    echo ${variable} # baba
    echo ${!variable} # booba
    

    경우와 $2.

  4. 을 거거에 넣기argAry1=("${!1}") 작성하다argAry1=를 했습니다.descTable[@]argAry1=("${descTable[@]}")★★★★★★★★★★★★★★★★★☆declare요요없없없없다다

주의: 이 브래킷 폼을 사용하여 어레이를 초기화하면 다음 항목에 따라 새로운 어레이가 초기화됩니다.IFS또는 기본적으로 탭, 바꿈 공백인 내부 필드 구분 기호를 사용합니다.그 경우, 그것이 사용되었기 때문에[@](따옴표기()는 다음과 같습니다.[*]를 참조해 주세요.

예약은 이쪽입니다.

»BASH variable 서 호출되는 는 "로컬 범위"가takes_ary_as_arg()descTable[@] ★★★★★★★★★★★★★★★★★」optsTable[@]이치노

그렇다면 이러한 변수 자체를 직접 살펴보는 것은 어떨까요?마치 여기에 글을 쓰는 것 같다.

argAry1=("${descTable[@]}")

해 주세요.「 」를 카피하기만 하면 됩니다.이 설명은 복사만 하면 됩니다.descTable[@] 값에 값IFS.

정리하다

이것은 본질적으로 가치로 넘어가는 것이 아닙니다.평소처럼요.

위의 Dennis Williamson의 코멘트도 강조하고 싶습니다.스퍼스 어레이(키가 정의되어 있지 않은 어레이는, 「구멍」이 있는 어레이」는 예상대로 동작하지 않습니다.키를 느슨하게 해 어레이를 「응축」합니다.

즉, 일반화의 가치를 알 수 있으므로 함수는 이름을 몰라도 어레이(또는 복사본)를 가져올 수 있습니다.

  • ~"keys"의 경우: 이 기법은 충분합니다.인덱스(키)가 없어졌음을 인식하기만 하면 됩니다.
  • 실제 복사본의 경우: 다음과 같이 키에 대한 평가를 사용할 수 있습니다.

    eval local keys=(\${!$1})
    

그리고 그것들을 사용하여 복사본을 만드는 루프입니다. 의 : note!는, 이전의 간접/이중 평가를 사용하지 않고, 어레이 컨텍스트에서는 어레이 인덱스(키)를 반환합니다.

  • 물론 ,,를 통과한다면 약면면면면면면면면면면면면면면면면면면면면.descTable ★★★★★★★★★★★★★★★★★」optsTable 없음)[@]를 사용할 수 .eval . 이치노

여기서 기본적인 문제는 어레이를 설계/실장하는 bash 개발자가 실제로 문제를 일으켰다는 것입니다.은 들들 that that that that 로 결정했다.${array}이 짧다${array[0]}특히했을 때${array[0]}는 의미가 없으며 어레이 유형이 관련성이 있는 경우 빈 문자열로 평가됩니다.

하면 배열을 할당하는 .array=(value1 ... valueN)는 "value value"라는 구문을 .[subscript]=string따라서 어레이 내의 특정 인덱스에 직접 값을 할당합니다.이를 통해 수치 인덱스와 해시 인덱스(bash 용어로 연관 배열이라고 함)의 두 가지 유형의 배열을 사용할 수 있습니다.또한 희박한 수치 인덱스 배열을 생성할 수도 있습니다.<고객명>을합니다.[subscript]=부품은 숫자 인덱스 배열의 단수이며, 순서형 색인 0부터 시작하여 할당문의 새 값에 따라 증가합니다.

therefore그 、${array}어레이 전체, 인덱스 및 모든 것을 평가해야 합니다.과제문의 역순으로 평가해야 합니다.CS전공 3학년이라면 누구나 그것을 알아야 한다.이 경우 이 코드는 예상대로 작동합니다.

declare -A foo bar
foo=${bar}

그런 다음 값별로 배열을 함수에 전달하고 한 배열을 다른 배열을 할당하면 나머지 셸 구문에 따라 작동합니다. 제대로 연산자 지지 but만 、 butment 、 당 but 、 당 but 。=에 값으로 수 (배열은 일반적으로 사용할 수 없습니다.또한 어레이를 기능이나 서브셸, 출력에 값으로 전달할 수 없습니다.(echo ${array}모든 것을 검토하기 위한 코드가 없습니다.

따라서 올바르게 수행했다면 다음 예시는 bash에서 어레이의 유용성이 크게 향상될 수 있음을 보여줍니다.

simple=(first=one second=2 third=3)
echo ${simple}

결과 출력은 다음과 같습니다.

(first=one second=2 third=3)

그러면 어레이가 할당 연산자를 사용하여 함수와 다른 셸 스크립트에 값에 따라 전달될 수 있습니다.파일로 출력하여 쉽게 저장할 수 있으며 파일에서 스크립트로 쉽게 로드할 수 있습니다.

declare -A foo
read foo <file

아아, 우리는 다른 최고의 bash 개발팀에게 실망을 당했습니다.

따라서 배열을 함수에 전달하려면 nameref 기능을 사용하는 옵션이1개밖에 없습니다.

function funky() {
    local -n ARR

    ARR=$1
    echo "indexes: ${!ARR[@]}"
    echo "values: ${ARR[@]}"
}

declare -A HASH

HASH=([foo]=bar [zoom]=fast)
funky HASH # notice that I'm just passing the word 'HASH' to the function

그러면 다음과 같은 출력이 생성됩니다.

indexes: foo zoom
values: bar fast

참조를 통해 전달되므로 함수의 배열에 할당할 수도 있습니다.네, 참조되는 어레이는 글로벌 범위를 가져야 하지만 셸 스크립팅이라는 점을 고려하면 큰 문제는 아닙니다.값별로 연관지을 수 있는 인덱스 배열 또는 스파스 인덱스 배열을 함수에 전달하려면 다음과 같은 단일 문자열로 모든 인덱스 및 값을 인수 목록으로 보내야 합니다(대형 배열인 경우 그다지 유용하지 않음).

funky "${!array[*]}" "${array[*]}"

함수 내부에 코드를 많이 작성하여 어레이를 재구성합니다.

DevSolar의 답변에는 제가 이해할 수 없는 점이 하나 있습니다(특정 이유가 있을 수 있지만 어떤 것도 생각나지 않습니다).위치 매개변수 요소에서 요소별, 반복 배열을 설정합니다.

더 쉬운 직책은

called_function()
{
  ...
  # do everything like shown by DevSolar
  ...

  # now get a copy of the positional parameters
  local_array=("$@")
  ...
}

여러 배열을 매개 변수로 전달하는 쉬운 방법은 문자로 구분된 문자열을 사용하는 것입니다.스크립트를 다음과 같이 호출할 수 있습니다.

./myScript.sh "value1;value2;value3" "somethingElse" "value4;value5" "anotherOne"

그런 다음 코드 내에서 다음과 같이 추출할 수 있습니다.

myArray=$1
IFS=';' read -a myArray <<< "$myArray"

myOtherArray=$3
IFS=';' read -a myOtherArray <<< "$myOtherArray"

이렇게 하면 실제로 여러 어레이를 매개 변수로 전달할 수 있으며 마지막 매개 변수로 지정할 필요가 없습니다.

function aecho {
  set "$1[$2]"
  echo "${!1}"
}

$ foo=(dog cat bird)

$ aecho foo 1
cat

bash에서 참조를 통해 일반 어레이 및 관련 어레이를 매개 변수로 전달하는 방법

최신 bash(버전 4.3 이후)에서는 어레이를 참조 전달할 수 있습니다.아래에 보여드릴게요.어레이를 수동으로 시리얼화역직렬화하려면 bash 일반 "인덱스화" 어레이에 대해서여기를, bash 관련 어레이에 대해서여기를 참조하십시오.값별 또는 참조별 어레이 인쇄에 대해서는, 여기를 참조해 주세요.

단, 아래 그림과 같이 어레이를 레퍼런스 방식으로 전달하는 것이 훨씬 쉽고 보다 세심한 작업이므로 이를 권장합니다.

아래 코드는 eRCaGuy_hello_world repo에서도 온라인으로 이용할 수 있습니다.array_pass_as_bash_parameter_by_reference.sh.array_pass_as_bash_parameter_2_associative.sh 의 예도 참조해 주세요.

일반 bash 어레이의 데모를 다음에 나타냅니다.

function foo {
    # declare a local **reference variable** (hence `-n`) named `data_ref`
    # which is a reference to the value stored in the first parameter
    # passed in
    local -n data_ref="$1"
    echo "${data_ref[0]}"
    echo "${data_ref[1]}"
}

# declare a regular bash "indexed" array
declare -a data
data+=("Fred Flintstone")
data+=("Barney Rubble")
foo "data"

샘플 출력:

Fred Flintstone
Barney Rubble

관련지어져 있는 bash 어레이(bash 해시 테이블, "비밀번호 맵" 또는 "순서 없는 맵")의 데모를 다음에 나타냅니다.

function foo {
    # declare a local **reference variable** (hence `-n`) named `data_ref`
    # which is a reference to the value stored in the first parameter
    # passed in
    local -n data_ref="$1"
    echo "${data_ref["a"]}"
    echo "${data_ref["b"]}"
}

# declare a bash associative array
declare -A data
data["a"]="Fred Flintstone"
data["b"]="Barney Rubble"
foo "data"

샘플 출력:

Fred Flintstone
Barney Rubble

참고 자료:

  1. @Todd Leman의 답변에서 위의 코드 샘플을 수정했습니다.Bash에서 관련 어레이를 인수로 함수에 전달하려면 어떻게 해야 합니까?
  2. 수동 시리얼화/디시리얼화 답변도 참조하십시오.
  3. 여기서 후속 질문을 드리겠습니다.페이지에-n 및 Atribute cannot be apply to array variables라고 기재되어 있는데, Atribute가 가능한 이유는 무엇입니까?

이 기능은 공백에서도 사용할 수 있습니다.

format="\t%2s - %s\n"

function doAction
{
  local_array=("$@")
  for (( i = 0 ; i < ${#local_array[@]} ; i++ ))
    do
      printf "${format}" $i "${local_array[$i]}"
  done
  echo -n "Choose: "
  option=""
  read -n1 option
  echo ${local_array[option]}
  return
}

#the call:
doAction "${tools[@]}"

몇 가지 트릭을 사용하면 명명된 파라미터를 실제로 어레이와 함께 함수에 전달할 수 있습니다.

내가 개발한 방법을 사용하면 다음과 같은 함수에 전달된 파라미터에 액세스할 수 있습니다.

testPassingParams() {

    @var hello
    l=4 @array anArrayWithFourElements
    l=2 @array anotherArrayWithTwo
    @var anotherSingle
    @reference table   # references only work in bash >=4.3
    @params anArrayOfVariedSize

    test "$hello" = "$1" && echo correct
    #
    test "${anArrayWithFourElements[0]}" = "$2" && echo correct
    test "${anArrayWithFourElements[1]}" = "$3" && echo correct
    test "${anArrayWithFourElements[2]}" = "$4" && echo correct
    # etc...
    #
    test "${anotherArrayWithTwo[0]}" = "$6" && echo correct
    test "${anotherArrayWithTwo[1]}" = "$7" && echo correct
    #
    test "$anotherSingle" = "$8" && echo correct
    #
    test "${table[test]}" = "works"
    table[inside]="adding a new value"
    #
    # I'm using * just in this example:
    test "${anArrayOfVariedSize[*]}" = "${*:10}" && echo correct
}

fourElements=( a1 a2 "a3 with spaces" a4 )
twoElements=( b1 b2 )
declare -A assocArray
assocArray[test]="works"

testPassingParams "first" "${fourElements[@]}" "${twoElements[@]}" "single with spaces" assocArray "and more... " "even more..."

test "${assocArray[inside]}" = "adding a new value"

즉, 파라미터의 이름을 사용하여 파라미터를 호출할 수 있을 뿐만 아니라 실제로 어레이를 전달할 수 있습니다(및 변수에 대한 참조 - 이 기능은 bash 4.3에서만 작동합니다).또한 매핑 변수는 모두 $1(기타)과 마찬가지로 로컬 범위 내에 있습니다.

이 기능을 하는 코드는 매우 가볍고 bash 3과 bash 4에서 모두 작동합니다(테스트한 버전은 이것뿐입니다).만약 당신이 bash를 이용한 개발을 훨씬 더 멋지고 쉽게 만드는 이런 트릭에 관심이 있다면, 당신은 내 Bash Infinity Framework를 볼 수 있습니다. 아래 코드는 그 목적을 위해 개발되었습니다.

Function.AssignParamLocally() {
    local commandWithArgs=( $1 )
    local command="${commandWithArgs[0]}"

    shift

    if [[ "$command" == "trap" || "$command" == "l="* || "$command" == "_type="* ]]
    then
        paramNo+=-1
        return 0
    fi

    if [[ "$command" != "local" ]]
    then
        assignNormalCodeStarted=true
    fi

    local varDeclaration="${commandWithArgs[1]}"
    if [[ $varDeclaration == '-n' ]]
    then
        varDeclaration="${commandWithArgs[2]}"
    fi
    local varName="${varDeclaration%%=*}"

    # var value is only important if making an object later on from it
    local varValue="${varDeclaration#*=}"

    if [[ ! -z $assignVarType ]]
    then
        local previousParamNo=$(expr $paramNo - 1)

        if [[ "$assignVarType" == "array" ]]
        then
            # passing array:
            execute="$assignVarName=( \"\${@:$previousParamNo:$assignArrLength}\" )"
            eval "$execute"
            paramNo+=$(expr $assignArrLength - 1)

            unset assignArrLength
        elif [[ "$assignVarType" == "params" ]]
        then
            execute="$assignVarName=( \"\${@:$previousParamNo}\" )"
            eval "$execute"
        elif [[ "$assignVarType" == "reference" ]]
        then
            execute="$assignVarName=\"\$$previousParamNo\""
            eval "$execute"
        elif [[ ! -z "${!previousParamNo}" ]]
        then
            execute="$assignVarName=\"\$$previousParamNo\""
            eval "$execute"
        fi
    fi

    assignVarType="$__capture_type"
    assignVarName="$varName"
    assignArrLength="$__capture_arrLength"
}

Function.CaptureParams() {
    __capture_type="$_type"
    __capture_arrLength="$l"
}

alias @trapAssign='Function.CaptureParams; trap "declare -i \"paramNo+=1\"; Function.AssignParamLocally \"\$BASH_COMMAND\" \"\$@\"; [[ \$assignNormalCodeStarted = true ]] && trap - DEBUG && unset assignVarType && unset assignVarName && unset assignNormalCodeStarted && unset paramNo" DEBUG; '
alias @param='@trapAssign local'
alias @reference='_type=reference @trapAssign local -n'
alias @var='_type=var @param'
alias @params='_type=params @param'
alias @array='_type=array @param'

수용된 답변에 덧붙이자면 어레이의 내용이 다음과 같은 경우에는 제대로 작동하지 않습니다.

RUN_COMMANDS=(
  "command1 param1... paramN"
  "command2 param1... paramN"
)

이 경우 어레이의 각 멤버가 분할되므로 기능에 표시되는 어레이는 다음과 같습니다.

RUN_COMMANDS=(
    "command1"
    "param1"
     ...
    "command2"
    ...
)

이 문제를 해결하려면 변수 이름을 함수에 전달하고 eval을 사용하는 방법을 찾았습니다.

function () {
    eval 'COMMANDS=( "${'"$1"'[@]}" )'
    for COMMAND in "${COMMANDS[@]}"; do
        echo $COMMAND
    done
}

function RUN_COMMANDS

단 2©

다음은 어레이를 명시적으로 전달하지 않고 어레이에 대응하는 변수만 전달하면 되는 회피책입니다.

function passarray()
{
    eval array_internally=("$(echo '${'$1'[@]}')")
    # access array now via array_internally
    echo "${array_internally[@]}"
    #...
}

array=(0 1 2 3 4 5)
passarray array # echo's (0 1 2 3 4 5) as expected

할 수 저는 보다 더 을 알게 되었습니다."{array[@]"} 후, 「」를 사용해 합니다.array_inside=("$@") 위치/보다 하다가 있을 때 .getopts파라미터를 지정합니다. 먼저 되지 않은 해야 합니다 파라미터의 에 관련되지 않은 파라미터를 삭제해야 합니다.shift및 어레이 요소를 제거합니다.

순수론자의 관점에서는 이 접근방식을 언어 위반으로 간주할 가능성이 높지만, 실용적으로 말하면, 이 접근방식은 많은 슬픔을 덜어주었다.되는 토픽에 는, 「아까운 친구」를 사용하고 있습니다.」를 하고 있습니다.evaltarget_varname다음 함수로 넘어갑니다.

eval $target_varname=$"(${array_inside[@]})"

이게 도움이 됐으면 좋겠네요.

짧은 답변은 다음과 같습니다.

function display_two_array {
    local arr1=$1
    local arr2=$2
    for i in $arr1
    do
       echo "arrary1: $i"
    done
    
    for i in $arr2
    do
       echo "arrary2: $i"
    done
}

test_array=(1 2 3 4 5)
test_array2=(7 8 9 10 11)

display_two_array "${test_array[*]}" "${test_array2[*]}"

「 」의 에 주의해 주세요.${test_array[*]} ★★★★★★★★★★★★★★★★★」${test_array2[*]}"로 둘러싸야 합니다.그렇지 않으면 실패합니다.

수동 해석 및 시리얼화/디시리얼화를 통해 일반 어레이를 bash 값별로 파라미터로 전달하는 방법

다음 답변은 bash 일반 "인덱스화" 어레이를 기본적으로 직렬화역직렬화함으로써 함수에 매개 변수로 전달하는 방법을 보여 줍니다.

  1. 일반 인덱스 어레이 대신 bash 관련 어레이(해시 테이블)에 대해 이 수동 직렬화/비직렬화를 보려면 여기를 참조하십시오.
  2. 어레이를 참조 통과시키는 더 나은 방법(bash 버전 4.3 이후가 필요함)에 대해서는 위의 링크와 다른 답변을 참조하십시오.
    1. 레퍼런스로 어레이를 전달하는 것이 훨씬 쉽고, 보다 세심한 작업이 되기 때문에, 지금 추천하는 것은 이것입니다.따라서 아래에 나타내는 수동 시리얼화/디시리얼화 기술도 매우 유익하고 유용합니다.

간단한 요약:

아래 3개의 개별 함수 정의를 참조하십시오.어떻게 통과해야 할지 검토한다.

  1. 함수에 대한 단일 bash 배열
  2. 이상의 bash 어레이를 함수에 할당하고,
  3. 두 개 이상의 bash 배열과 함수에 대한 추가 인수(배열 전후)를 추가합니다.

12년이 지났지만, 저는 여전히 제가 정말 좋아하는 답을 찾을 수 없습니다. 그리고 제가 그냥 사용할 수 있을 만큼 충분히 철저하고, 충분히 단순하고, "논리적인" 답변은 제가 필요할 때 다시 찾아와서 복사하고, 붙여넣고, 확장할 수 있습니다.자, 여기 제가 이 모든 것으로 생각하는 답변이 있습니다.

bash 배열을 bash 함수에 매개 변수로 전달하는 방법

명령어를스크립트의 할 수 다음 되는 각 변화할 수 있기 에 bash "는 "변수 구문 분석"입니다.이렇게 어레이기본적으로 됩니다."${array1[@]}".

아래의 모든 코드 예에서는 테스트용으로 다음 2개의 bash 어레이가 있다고 가정합니다.

array1=()
array1+=("one")
array1+=("two")
array1+=("three")

array2=("four" "five" "six" "seven" "eight")

위와 아래의 코드는 my bash/array_pass_as_bash_parameter로 사용할 수 있습니다.sh 파일은 GitHub의 eRCaGuy_hello_world repo에 있습니다.

예 1: 하나의 bash 어레이를 함수에 전달하는 방법

배열을 bash 함수에 전달하려면 모든 요소를 개별적으로 전달해야 합니다.지정된 bash 배열array1은 " " " " 입니다."${array1[@]}". 함수 실행 는 bash라는 매직 bash는 매직 bash를 사용합니다@는 를 사용하여 수 "$@"구문(아래 그림 참조해 주세요.

함수 정의:

# Print all elements of a bash array.
# General form:
#       print_one_array array1
# Example usage:
#       print_one_array "${array1[@]}"
print_one_array() {
    for element in "$@"; do
        printf "    %s\n" "$element"
    done
}

사용 예:

echo "Printing array1"
# This syntax passes all members of array1 as separate input arguments to 
# the function
print_one_array "${array1[@]}"

출력 예:

Printing array1
    one
    two
    three

예 2: 두 이상의 bash 어레이를 함수에 전달하는 방법...

(입력 어레이를 다시 별도의 bash 어레이로 재확보하는 방법)

여기서는 어떤 수신 파라미터가 어떤 어레이에 속하는지 구별해야 합니다.그러기 위해서는 각 어레이의 크기를 알아야 합니다.즉, 각 어레이의 요소 수를 의미합니다.이는 C의 어레이를 통과하는 것과 매우 유사하며, 일반적으로 C 함수에 전달되는 어레이 길이를 알아야 합니다.지정된 bash 배열array1 그는 , 로 수 ."${#array1[@]}"의).#기호)입력 인수의 위치를 알기 위해array_lenlength 파라미터는 다음과 같이 개별 어레이 요소를 전달하기 전에 어레이어레이 길이 파라미터를 항상 전달해야 합니다.

어레이를 해석하려면 input argument array에서 어레이 슬라이싱을 사용합니다.@.

bash 어레이 슬라이싱 구문이 어떻게 동작하는지 알려드립니다(여기 답변 참조).슬라이싱 구문에서:start:length수 있는 이고 두 는 잡을 의 수입니다

# array slicing basic format 1: grab a certain length starting at a certain
# index
echo "${@:2:5}"
#         │ │
#         │ └────> slice length
#         └──────> slice starting index (zero-based)

# array slicing basic format 2: grab all remaining array elements starting at a
# certain index through to the end
echo "${@:2}"
#         │
#         │
#         └──────> slice starting index (zero-based)

입력 새 배열로 안에 .() 예를 ("${@:$i:$array1_len}")바깥쪽 괄호는 중요합니다.배쉬하다

다음 예에서는 2개의 bash 어레이만 허용하지만 지정된 패턴을 따르면 임의의 수의 bash 어레이를 인수로 허용하도록 쉽게 조정할 수 있습니다.

함수 정의:

# Print all elements of two bash arrays.
# General form (notice length MUST come before the array in order
# to be able to parse the args!):
#       print_two_arrays array1_len array1 array2_len array2
# Example usage:
#       print_two_arrays "${#array1[@]}" "${array1[@]}" \
#       "${#array2[@]}" "${array2[@]}"
print_two_arrays() {
    # For debugging: print all input args
    echo "All args to 'print_two_arrays':"
    print_one_array "$@"

    i=1

    # Read array1_len into a variable
    array1_len="${@:$i:1}"
    ((i++))
    # Read array1 into a new array
    array1=("${@:$i:$array1_len}")
    ((i += $array1_len))

    # Read array2_len into a variable
    array2_len="${@:$i:1}"
    ((i++))
    # Read array2 into a new array
    array2=("${@:$i:$array2_len}")
    ((i += $array2_len))

    # Print the two arrays
    echo "array1:"
    print_one_array "${array1[@]}"
    echo "array2:"
    print_one_array "${array2[@]}"
}

사용 예:

echo "Printing array1 and array2"
print_two_arrays "${#array1[@]}" "${array1[@]}" "${#array2[@]}" "${array2[@]}"

출력 예:

Printing array1 and array2
All args to 'print_two_arrays':
    3
    one
    two
    three
    5
    four
    five
    six
    seven
    eight
array1:
    one
    two
    three
array2:
    four
    five
    six
    seven
    eight

예 3: 2개의 bash 어레이와 그 후의 추가 arg를 함수에 전달합니다.

이것은 위 예의 작은 확장입니다.또한 위의 예시와 같이 bash 배열 슬라이싱을 사용합니다.단, 2개의 완전한 입력 어레이를 해석한 후에 정지하는 것이 아니라 마지막에 몇 개의 인수를 해석하는 것으로 계속합니다.이 패턴은 임의의 수의 bash 어레이와 임의의 수의 추가 인수에 대해 무기한 계속할 수 있습니다.단, 각 bash 어레이의 길이가 해당 어레이의 요소 바로 앞에 있는 한 모든 입력 인수 순서를 수용할 수 있습니다.

함수 정의:

# Print all elements of two bash arrays, plus two extra args at the end.
# General form (notice length MUST come before the array in order
# to be able to parse the args!):
#       print_two_arrays_plus_extra_args array1_len array1 array2_len array2 \
#       extra_arg1 extra_arg2
# Example usage:
#       print_two_arrays_plus_extra_args "${#array1[@]}" "${array1[@]}" \
#       "${#array2[@]}" "${array2[@]}" "hello" "world"
print_two_arrays_plus_extra_args() {
    i=1

    # Read array1_len into a variable
    array1_len="${@:$i:1}"
    ((i++))
    # Read array1 into a new array
    array1=("${@:$i:$array1_len}")
    ((i += $array1_len))

    # Read array2_len into a variable
    array2_len="${@:$i:1}"
    ((i++))
    # Read array2 into a new array
    array2=("${@:$i:$array2_len}")
    ((i += $array2_len))

    # You can now read the extra arguments all at once and gather them into a
    # new array like this:
    extra_args_array=("${@:$i}")

    # OR you can read the extra arguments individually into their own variables
    # one-by-one like this
    extra_arg1="${@:$i:1}"
    ((i++))
    extra_arg2="${@:$i:1}"
    ((i++))

    # Print the output
    echo "array1:"
    print_one_array "${array1[@]}"
    echo "array2:"
    print_one_array "${array2[@]}"
    echo "extra_arg1 = $extra_arg1"
    echo "extra_arg2 = $extra_arg2"
    echo "extra_args_array:"
    print_one_array "${extra_args_array[@]}"
}

사용 예:

echo "Printing array1 and array2 plus some extra args"
print_two_arrays_plus_extra_args "${#array1[@]}" "${array1[@]}" \
"${#array2[@]}" "${array2[@]}" "hello" "world"

출력 예:

Printing array1 and array2 plus some extra args
array1:
    one
    two
    three
array2:
    four
    five
    six
    seven
    eight
extra_arg1 = hello
extra_arg2 = world
extra_args_array:
    hello
    world

참고 자료:

  1. 여기서 eRCaGuy_hello_world repo의 샘플 코드를 많이 참조했습니다.
    1. array_practice 를 실행합니다.
    2. array_sysloging_syslog.
  2. [bash 어레이 슬라이싱에 대한 답변]유닉스 Linux: Bash: 위치 파라미터 슬라이스
  3. "Bash에서 모든 입력 args("$@")의 백업 복사본을 만들고 사용하는 방법"에 대한 질문에 대한 답변입니다. 입력 인수 배열의 일반적인 어레이 조작에 매우 유용합니다.
  4. "Bash의 함수에 인수로서 어레이를 전달하는 방법"에 대한 답변입니다.이 답변은 다음과 같은 매우 중요한 개념을 확인시켜 줍니다.

    배열을 전달할 수 없습니다. 요소(확장된 배열)만 전달할 수 있습니다.

다음 항목도 참조하십시오.

  1. [이 주제에 대한 또 다른 답변]배열을 Bash 함수에 인수로 넘기는 방법

요건:배열에서 문자열을 찾는 함수입니다.
이는 DevSolar 솔루션을 복사하는 것이 아니라 전달된 인수를 사용한다는 점에서 약간 단순화한 것입니다.

myarray=('foobar' 'foxbat')

function isInArray() {
  local item=$1
  shift
  for one in $@; do
    if [ $one = $item ]; then
      return 0   # found
    fi
  done
  return 1       # not found
}

var='foobar'
if isInArray $var ${myarray[@]}; then
  echo "$var found in array"
else
  echo "$var not found in array"
fi 

어레이를 사용하여 json 파일을 만들고 jq를 사용하여 해당 json 파일을 구문 분석할 수도 있습니다.

예를 들어 다음과 같습니다.

my-array.json:

{
  "array": ["item1","item2"]
}

script.sh:

ARRAY=$(jq -r '."array"' $1 | tr -d '[],"')

그런 다음 스크립트를 호출합니다.

script.sh ./path-to-json/my-array.json

다음 유사한 질문에서 더 많은 아이디어를 찾을 수 있습니다.배열을 인수로 Bash 함수에 전달하는 방법

언급URL : https://stackoverflow.com/questions/1063347/passing-arrays-as-parameters-in-bash

반응형