Bash에서 명령 행 인수를 배열로 변환


161

명령 줄 인수를 bash 스크립트 배열로 어떻게 변환합니까?

나는 이것을 가지고 싶다 :

./something.sh arg1 arg2 arg3

그것을로 변환

myArray=( arg1 arg2 arg3 )

스크립트에서 추가로 사용하기 위해 myArray를 사용할 수 있습니다.

이 이전 SO 게시물은 가깝지만 배열을 만드는 방법에 대해서는 다루지 않습니다. Bash에서 명령 줄 인수를 어떻게 구문 분석합니까?

인수를 일반 bash 스크립트 배열로 변환해야합니다. 다른 언어 (예 : Python)를 사용할 수 있지만 bash 에서이 작업을 수행해야한다는 것을 알고 있습니다. "추가"기능 또는 이와 유사한 것을 찾고 있습니까?

업데이트 : 또한 제로 인수를 확인하고 기본 배열 값을 지정하는 방법을 묻고 싶었고 아래 답변 덕분 에이 작업을 수행 할 수있었습니다.

if [ "$#" -eq 0 ]; then
  myArray=( defaultarg1 defaultarg2 )
else
  myArray=( "$@" )
fi

답변:


207

실제로 명령 행 인수는 실제로 는 이미 배열과 같습니다. 최소한 $@변수를 배열처럼 취급 할 수 있습니다 . 즉, 다음과 같이 실제 배열로 변환 할 수 있습니다.

myArray=( "$@" )

인수를 입력하고 $@값에 입력하려면 set다음을 사용하십시오 .

$ set -- apple banana "kiwi fruit"
$ echo "$#"
3
$ echo "$@"
apple banana kiwi fruit

인수 구조를 사용하는 방법을 이해하는 것은 POSIX sh에서 특히 유용합니다.


2
감사! 잘 작동합니다! 인수가 없는지 확인하고 기본 배열 값을 할당하는 방법을 묻기 위해 $ #가 완벽하게 작동합니다!
Suman

1
set범위에 대한 위치 매개 변수를 설정할 수 있습니다. 쉘 옵션을 설정할 수도 있습니다. 을 수행 할 수 있습니다 set foo. 이는 $1"foo"로 확장됨을 의미 하지만 매개 변수가 대시로 시작 set하면 쉘 옵션을 설정하는 것으로 가정합니다. 이중 대시는 다음의 모든 매개 변수가 설정 될 위치 매개 변수로 해석되도록합니다.
kojiro

12
하나의 문제 : echo $@모든 인수를 인쇄하지만 echo $myArray첫 번째 요소 만 인쇄합니다. 모두 보려면을 사용하십시오 echo ${myArray[@]}.
z0r

4
@ z0r 만약 당신이 그 확장에 큰 따옴표를 넣지 않으면 bash는 그것들을 다시 단어 분리 할 것이고, 의미를 잃을 수도 있습니다.
kojiro

맞습니다. 배열을 "스 플래트"하고 각 요소를 사용하는 일반적인 방법은 "${myArray[@]}"입니다. 배열을 반복하려면 IFS에서 개별 요소가 분리되지 않도록 따옴표가 필요합니다.
BallpointBen

66

아마도 이것이 도움이 될 수 있습니다.

myArray=("$@") 

또한 'in'을 생략하여 인수를 반복 할 수 있습니다.

for arg; do
   echo "$arg"
done

동등 할 것이다

for arg in "${myArray[@]}"; do
   echo "$arg"
done

3
초보자 질문 : bash는 arg필드 에 넣을 내용을 어떻게 알 수 있습니까? 사전 정의 된 변수입니까? ${var}의 콘텐츠로 확장되었습니다 var.${var[n]}narray 요소 의 내용으로 확장됩니다 var. 되어 ${var[@]}다음 전체 배열, 즉 확장 ${var[0]} ${var[1]} ... ${var[n]}(와 n마지막 요소의 인덱스 인)?
Christian

4
[in]이없는 [for]는 인수 배열 $ @ ($ 1, $ 2 등)를 반복합니다. [set] 명령으로 설정할 수도 있습니다 (예 : set-arg1 arg2).
Nahuel Fouilleul

17

실제로 매개 변수 목록은 $1 $2 ...etc 로 액세스 할 수 있습니다 .
이는 정확히 다음과 같습니다.

${!i}

그래서, 매개 변수의 목록이 세트로 변경 될 수 있습니다,
그리고 ${!i}그들에 액세스 할 수있는 올바른 방법은 다음과 같습니다

$ set -- aa bb cc dd 55 ff gg hh ii jjj kkk lll
$ for ((i=0;i<=$#;i++)); do echo "$#" "$i" "${!i}"; done
12 1 aa
12 2 bb
12 3 cc
12 4 dd
12 5 55
12 6 ff
12 7 gg
12 8 hh
12 9 ii
12 10 jjj
12 11 kkk
12 12 lll

특정 경우, 배열이 필요하지 않은 경우 인수 목록을 설정하기 위해 (배열이 필요없는) 다음을 사용할 수 있습니다.

if [ "$#" -eq 0 ]; then
    set -- defaultarg1 defaultarg2
fi

이것은 더 간단한 표현으로 해석됩니다.

[ "$#" == "0" ] && set -- defaultarg1 defaultarg2

에코 예제는 다음과 같아서는 안됩니다. echo "$#" "$i+1" "${!i}";표시된대로 정확하게 출력을 얻으려면?
Zael

6

다른 사용법은 다음과 같습니다.

#!/bin/bash
array=( "$@" )
arraylength=${#array[@]}
for (( i=0; i<${arraylength}; i++ ));
do
   echo "${array[$i]}"
done

4

더 쉽게, 그러나 직접 작업 할 수 있습니다 $@;)

프롬프트에서 직접 args 목록을 전달하는 방법은 다음과 같습니다.

function echoarg { for stuff in "$@" ; do echo $stuff ; done ; } 
    echoarg Hey Ho Lets Go
    Hey
    Ho
    Lets
    Go

1
더 쉬운 방법 for stuff in "$@" ; do ...for stuff ; do ...:)
kkm

1

배열과 $ @가 실제로 동일한 방식을 나란히 보여줍니다.

암호:

#!/bin/bash

echo "Dollar-1 : $1"
echo "Dollar-2 : $2"
echo "Dollar-3 : $3"
echo "Dollar-AT: $@"
echo ""

myArray=( "$@" )

echo "A Val 0: ${myArray[0]}"
echo "A Val 1: ${myArray[1]}"
echo "A Val 2: ${myArray[2]}"
echo "A All Values: ${myArray[@]}"

입력:

./bash-array-practice.sh 1 2 3 4

산출:

Dollar-1 : 1
Dollar-2 : 2
Dollar-3 : 3
Dollar-AT: 1 2 3 4

A Val 0: 1
A Val 1: 2
A Val 2: 3
A All Values: 1 2 3 4

1

큰 따옴표의 중요성은 강조 할 가치가 있습니다. 인수에 공백이 있다고 가정하십시오.

암호:

#!/bin/bash
printf 'arguments:%s\n' "$@"
declare -a arrayGOOD=( "$@" )
declare -a arrayBAAD=(  $@  )

printf '\n%s:\n' arrayGOOD
declare -p arrayGOOD
arrayGOODlength=${#arrayGOOD[@]}
for (( i=1; i<${arrayGOODlength}+1; i++ ));
do
   echo "${arrayGOOD[$i-1]}"
done

printf '\n%s:\n' arrayBAAD
declare -p arrayBAAD
arrayBAADlength=${#arrayBAAD[@]}
for (( i=1; i<${arrayBAADlength}+1; i++ ));
do
   echo "${arrayBAAD[$i-1]}"
done

산출:

> ./bash-array-practice.sh 'The dog ate the "flea" -- and ' the mouse.
arguments:The dog ate the "flea" -- and 
arguments:the
arguments:mouse.

arrayGOOD:
declare -a arrayGOOD='([0]="The dog ate the \"flea\" -- and " [1]="the" [2]="mouse.")'
The dog ate the "flea" -- and 
the
mouse.

arrayBAAD:
declare -a arrayBAAD='([0]="The" [1]="dog" [2]="ate" [3]="the" [4]="\"flea\"" [5]="--" [6]="and" [7]="the" [8]="mouse.")'
The
dog
ate
the
"flea"
--
and
the
mouse.
> 
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.