POSIX에서 공백으로 구분된 배열 요소를 연결하는 방법은 무엇입니까?

POSIX에서 공백으로 구분된 배열 요소를 연결하는 방법은 무엇입니까?

Bash 스크립트에서 작동하는 방법은 다음과 같습니다.

PACKAGES=(
    'curl'
    'git'
    'htop'
    'mc'
    'tree'
    'vim'
)

apt --yes install ${PACKAGES[@]}

하지만 POSIX에서 동일한 작업을 수행하여 #!/bin/sh스크립트에서 사용할 수 있도록 하려면 어떻게 해야 합니까?

답변1

POSIX sh셸에는 배열이 하나만 있습니다( $@위치 매개변수 배열, 즉 $1, $2, ...). 다음 명령을 사용하여 해당 값을 설정할 수 있습니다 set.

set -- curl git htop mc tree vim

또는 명령줄에서:

./myscript.sh curl git htop mc tree vim

그 다음에,

apt --yes install "$@"

참조를 확장하면 $@배열이 해당 참조로 확장됩니다.선두요소. 즉, $@배열에 합계가 포함되어 a word있으면 another word해당 "$@"항목으로 확장됩니다.끈. 인용하지 않으면 $@다음으로 확장됩니다.4개문자열 a, 및 .word​ 인용되지 않은 동작은 내용에 따라 다릅니다 .anotherword$IFS

Tai 에서는 bash큰따옴표 확장이 필요합니다 ${PACKAGES[@]}.

apt --yes install "${PACKAGES[@]}"

관련된:Unix Bourne Shell의 배열


당신은하지 않습니다진짜그러나 여기서는 "요소를 공백으로 연결"합니다. 예, echo값 사이에 공백이 생길 수 있지만 이것이 차이점입니다.

set -- a b c d
printf '>%s<\n' "$@"

이는

>a<
>b<
>c<
>d<

(4개의 개별 매개변수가 원하는 것입니다.)

그리고

printf '>%s<' "$*"

이는

>a b c d<

(요소가 있는 매개변수공간으로 연결됨( 명령에서 실제로 사용하려는 문자가 $IFS아닌 의 첫 번째 문자 )apt install

답변2

가지고 있는 것은 패키지 이름이므로 표준 셸을 사용하려는 경우 간단한 문자열 변수에 저장할 수 있습니다. 적어도데비안 매뉴얼에 따르면, 패키지 이름에는 문자만 포함될 수 있으며 -+.:~a-z0-9A-Z전역 문자나 공백은 없습니다.

따라서 다음은 괜찮을 것입니다.

#!/bin/sh
packages="curl git htop ..."
IFS=" "                           # make sure there's nothing weird here
apt --yes install $packages       # no quotes!

편집증이 있는 경우 set -f파일 이름 글로빙을 비활성화하려면 시작 부분에 추가하십시오. 이것은 공백만 문제로 남게 되지만 제정신의 시스템에서는 패키지 이름에 공백을 허용하지 않을 것이라고 생각합니다.

관련 정보