bash 스타일 배열을 애쉬로 이식하는 방법은 무엇입니까?


13

얼마 전에 나는 bash 스크립트를 작성했다.이 스크립트는 환경에서 실행할 수 있어야한다 ash.

에서 bash그것은 같았다 :

services=( "service1.service"
           "service2.service"                                       
           "service3.service" )  

for service in "${services[@]}"
do
   START $service                   
done

START()
{
   echo "Starting "$1
   systemctl start $1
}

실제로는 40 개의 서비스가 배열되어 있으며 가능한 한 고통없이 깨끗하게 전환하고 싶습니다. 항상 bashisms를 사용하고 있습니다. 이제 스크립트를보다 이식성있게 만드는 작업을 시작했습니다.

이식성의 이유로 순수한 ash솔루션 을 갖는 것이 좋을 것 입니다. 그러나 내가 busybox처분 할 때 꽤 견고하기 때문에 이식성을 희생 할 수 있습니다. "깨끗한"스크립트도 메트릭이므로 가독성이 크게 향상되는 경우에만 가능합니다.

이 경우 휴대용깨끗한 솔루션은 무엇입니까 ?

답변:


8

배열에 있었다 전에 bash, ksh및 기타 조개, 일반적인 방법은, 어느 요소에 없었던 구분 기호를 선택했다 (또는 필요 탈출 최소화하기 위해 드물었다 일), 그리고 반복 처리 모든 요소를 포함하는 문자열 이상 해당 구분 기호로 구분됩니다. 쉘은 이미 기본적으로 "단어"를 공백으로 분리하기 때문에 공백이 가장 편리한 분리 문자 선택입니다 (IFS를 다른 것으로 분리하려는 경우 IFS를 설정할 수 있음).

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

# backslash-escape any non-delimiter whitespace and all other characters that
# have special meaning to the shell, e.g. globs, parenthesis, ampersands, etc.
services='service1.service service2.service service3.service'

for s in $services ; do  # NOTE: do not double-quote $services here.
  START "$s"
done

$services해야 하지 우리가 있기 때문에 여기에 이중 인용 원하는 쉘 "단어"로 분할 할 수 있습니다.


3

ash에는 배열이 없습니다. 가까운 유일한 것은 위치 매개 변수이므로 할 수 있습니다.

set -- "service1.service" \
       "service2.service" \
       "service3.service"

for service in "$@"
do
   START $service
done

3

서비스 목록을 한 번만 참조해야하는 경우 here-doc을 사용할 수 있습니다.

while IFS= read -r service
do
   START "$service"
done << END
service1.service
service2.service
service3.service
END

서비스 이름은 목록에서 인용해서는 안됩니다 (그렇지 않은 "$service"이유가 없다면 인용해야합니다). 이 서비스의 이름은 들여 쓰기하고 싶은 경우, 사용 <<-대신 <<하고 탭 이름을 들여 :

while IFS= read -r service
do
   START "$service"
done <<- END
        service1.service
        service2.service
        service3.service
END
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.