2012-01-09 2 views
0

'123'형식의 스크립트 인수를 기반으로 bash의 배열에서 요소를 동적으로 삭제하려고합니다. 인수는 제거해야하는 배열의 인덱스로 가정합니다.배열 색인으로 'read -n 1'문자를 사용하여 배열 요소를 삭제할 수 없습니다.

#!/bin/bash 
# Doesn't delete an element. 
ARRAY=(a b c) 
while getopts ":a:" opt; do # run e.g. 'thisscript.h -a 0' 
    case $opt in 
     a) 
      echo -n $OPTARG |\ 
       while read -n 1 c; do 
        unset ARRAY[$c] 
       done 
       ;; 
    esac 
done 
echo ${ARRAY[@]} 
# Deletes an element successfully. 
ARRAY=(a b c) 
unset ARRAY[0] 
echo ${ARRAY[@]} 
# Deletes an element successfully. 
ARRAY=(a b c) 
n=0 
unset ARRAY[$n] 
echo ${ARRAY[@]} 

tmp.sh 파일, chmod + x tmp.sh를 실행하여 'tmp.sh -a 0'을 실행하십시오.

첫 번째 배열 요소 삭제 방법이 작동하지 않는 이유는 무엇이며 어떻게 '읽기 -n 1'컨텍스트 내에서 작동하게 할 수 있습니까?

답변

1

문제는 서브 쉘로 실행되는 PIPED while-read 루프입니다. 따라서 unset은 서브 쉘에서 발생하며 서브 쉘이 종료 될 때 사라집니다. 이것이 배열 변수에 영향을 미치지 않는 이유입니다.

이 문제는 고급 Bash 스크립팅 가이드 Section 20.2. Redirecting Code Blocks에 설명되어 있습니다.

다음은 파이프 대신 프로세스 대체를 사용하는 한 가지 해결 방법입니다.

while read -n 1 c; do 
    unset ARRAY[$c] 
done < <(echo -n $OPTARG) 
+0

얼마나 재미있는가요? 설명 덕분에 대단히 감사합니다. 귀하의 예제에서 double '<'의 사용법을 이해하고 싶지만 링크 된 페이지에서 '<<'문자열을 찾을 수 없습니다. Google에서 더 많은 정보를 찾을 수있는 구조의 이름이 있습니까? – KomodoDave

+0

'<(...)'구문을 프로세스 대체라고합니다. – dogbane

+0

설명대로 정확하게 - 내 잘못, 고마워! – KomodoDave