─━ IT ━─

셸 스크립트를 공유하고 통합하는 shsubrmerge

DKel 2021. 8. 16. 01:06
반응형
먼저 UNIX를 활용하는 툴 중의 하나가 셸 스크립트입니다.UNIX 에 준비되어 있는 커맨드를 조합하는 것으로, 필요로 하는 기능을 단시간에 효율적으로 실현할 수 있습니다.셸 스크립트는 통상, 그 파일 단체로 사용합니다.C언어로 작성된 명령어가 실행 시 다른 라이브러리를 링크하여 사용하는 것과 비교하면 대조적입니다.개별 파일로 동작하는 것은 편리하지만, 반면에 코드가 중복되기 쉽다는 문제도 안고 있습니다.본고에서는 셸 스크립트로 코드의 중복을 억제하면서도, 파일 단체에서 사용하는 편리성을 해치지 않기 위한 방법을 소개합니다.대상 독자 본고에서는, 어느 정도 셸 스크립트를 사용할 수 있는, 중급자부터 상급자를 독자로서 상정합니다.필요한 환경 소개 셸 스크립트를 실행하기 위해 필요한 환경은 최근의 UNIX 호환 OS입니다.여기서는 FreeBSD 5.3에서 동작을 확인하고 있습니다.셸 스크립트의 공유 함수 파일 셸 스크립트의 공유 라이브러리화와 관련하여 NetBSD가 새롭게 채택한 기동기구인 ′rc.d′ 이야기부터 시작합니다.지금까지 NetBSD는 BSD에서 유래하는 rc 기동 기구를 개량한 구조를 채용하고 있었습니다.이는 간소하고 다루기 쉬운 반면, 어플리케이션의 부팅이나 정지 처리를 추가하거나 삭제하는 것이 어렵다는 문제를 가지고 있었습니다.문제를 해결하는 방법으로는 SYSV4에서 유래한 init.d 부팅기구를 채용하면 되는데 이쪽에서도 부팅순서가 파일명순이거나 구조가 번잡하다는 문제가 있었습니다.물론 BSD rc 기동기구든, SYSV4 init.d 기동기구든, 기동처리를 하고 있는 것은 셸 스크립트입니다.그 셸 스크립트를 어떤 규칙으로 기동과 정지 처리에 사용하는가 하는 것이 여기서의 기동기구라는 것입니다.결국 오랜 논의 끝에 The NetBSD Project는 BSD rc 부팅기구와 SYSV4 init.d 부팅기구의 장점을 합친 것과 같은 NetBSD rc.d 부팅기구를 개발합니다.이 기구는 후에 FreeBSD에 이식되었습니다.NetBSD rc.d 기동 기구의 베이스가 되는 아이디어는, SYSV4 init.d 기동 기구로부터 가져오고 있습니다.이 때 부팅 스크립트로 관리가 어려웠던 원인 중 하나를 개선하는 방법이 제안되었습니다.SYSV4 init.d 기동 기구에서는, 1 서비스 마다 기동 스크립트 파일이 준비됩니다.각각의 스크립트 파일은 단체로 실행할 수 있도록 독립되어 있습니다.이는 편리한 일이지만 관리의 번거로움이라는 측면에서 문제가 있었습니다.모든 부팅 스크립트가 독립되어 있기 때문에 각각의 스크립트에는 모두 비슷한 코드가 들어가 있습니다.하나의 스크립트를 변경했다면, 다른 스크립트에 들어있는 똑같은 코드의 부분을 똑같이 변경을 할 필요가 있었습니다.이것은 귀찮고 빠뜨린 것도 있어 귀찮았습니다.The NetBSD Project에서는 이 문제를 해결하기 위해 부팅 스크립트에서 사용되는 처리를 공통된 함수로 작성하여 하나의 파일로 정리해 두기로 했습니다. ′/etc/rc.subr′이 그것입니다.그 결과 부팅 스크립트의 크기가 작아져서 전망이 좋아지고 공통 기능은 ′/etc/rc.subr′로 정리되어 있어 코드 중복이 없어졌습니다.이것은 관리면에서 매우 유용합니다.자주 사용하는 처리를 함수화하여 정리하는 여러 개의 셸 스크립트를 작성하다 보면 반드시 비슷한 처리를 하는 부분이 나타납니다.예를 들어 프로그램이 설치되어 있는지 알아보는 곳, usage를 출력하는 곳 등입니다.빈출하는 처리를 함수로 추출 파일로 정리해 두면 그 부분의 기술을 생략할 수 있습니다.예를 들어 리스트 3.1과 같은 함수 공유 파일을 만들었다고 합시다.리스트 3.1 공유 함수 파일 ′.shsubr′
# usage
# print usage
# usage
# usage _ msg = ′ usage message ′
# usage
#
usage ( )
{
echo ′ $ usage _ msg ′ 1 > & 2
}}개의 공유함수 파일을 사용하는 예를 리스트 3.2에 나타냅니다.이 명령어는, 아무것도 인수가 지정되어 있지 않은가-h 가 지정되어 있을 때는 사용법을 출력하고, 그렇지 않을 경우는 인수를 그대로 표준 출력으로 출력합니다.커맨드 쪽에서는 메시지를 설정하고 usage함수를 실행하고 있습니다. usage함수 자체는 .shsubr에 기술되어 있기 때문에 커맨드 자체에서는 기술되어 있지 않습니다.리스트 3.2 ′.shsubr′를 사용한 명령어 예시
# ! / bin / sh

. ′ $ { 0 % / * } ′ / . shsubr

usage _ msg = ′ usage :
command message
- h print help message ′

[ 0 = $ # ] && { usage ; exit ; }

echo ′$@′리스트 3.2 위에서 세 번째 줄로 리스트 3.3에서 리스트 3.1 파일을 읽어들이고 있습니다.리스트 3.3과 같이 기술되어 있는 경우, 명령어와 같은 디렉토리에 있는 「.shsubr」가 읽혀지게 됩니다.이렇게 해 두면, 커맨드와 같은 디렉토리에 「.shsubr」를 놓아 둘 수 있고, 파일명이 「.」로부터 시작되고 있으므로, 커맨드와 혼란할 일도 없습니다.리스트 3.3 ′.shsubr′ 읽기 처리
. ′${0%/*}′ /.shsubr 이렇게 공유함수를 작성해 두시면 편리합니다.하지만 편리한 반면 결점도 있습니다.다른 OS에 복사해서 사용하거나 네트워크에서 배포할 때 매우 번거롭습니다.지금까지 셸 스크립트에서 사용하는 범용적인 공유 함수 파일을 작성하는 일은 적극적으로 이루어지지 않았습니다.따라서 셸스크립트의 공유함수 파일명이나 공유함수 파일을 놓아두기 위한 디렉토리가 규격화되어 있지 않으며 관례도 없습니다.그렇기 때문에 파일을 여러 개로 나눠놓은 상태에서 배포를 하게 되면 사용하기 어렵습니다.분할된 것을 통합하는 셸 스크립트를 효과적으로 사용하기 위해서는 ′/etc/rc.subr′와 같은 공유함수 파일을 사용하는 것이 좋다는 것을 알고 있습니다.그러나, 셸 스크립트를 복수의 파일로 분할하면, 사용에 대한 공통 인식이 없기 때문에, 다른 환경에 가지고 갔을 때에 사용하기 어려워진다고 하는 문제가 있습니다.게다가 셸 스크립트는 편리하지만, 다른 사람에게는 읽기 어려워지기 십상이라는 문제도 있습니다.C언어라면 어느 정도 함수는 표준화 되어 있기 때문에 공통적으로 인식할 수 있는 코드가 많고 가독성도 상당히 있습니다.그러나 개인이 마음대로 작성한 함수가 사용된 셸 스크립트는 본인 이외에는 읽기 어려울 것입니다.셸스크립트의 내용을 변경하려고 파일을 열어보고, 자신이 전혀 모르는 함수가 많이 사용된다면 그 시점에서 지겨워질 것입니다.이 문제를 해결하려면 작성 시점에서는 공유함수 파일과 셸 스크립트를 분할해서 작업을 해 놓고 배포하는 단계에서 그것을 통합해서 하나의 파일로 만들어 놓으면 됩니다.통합 작업은 수작업으로 해도 좋지만 일일이 손으로 작업하면 모처럼 셸 스크립트를 사용하는 의미가 없습니다.공유함수 파일과 셸 스크립트를 통합해서 하나의 파일로 만들 셸 스크립트를 작성하시면 됩니다.공유함수 파일과 셸 스크립트를 Marge하는 shsubrmerge 명령어는 공유함수 파일과 셸 스크립트를 Marge하여 단일체로 동작하는 셸 스크립트를 생성합니다.shsubrmerge 명령어는 topless라고 하는 명령어를 배포하기 위해서 작성되었는데, 당초 이 셸스크립트는 FreeBSD에서 공유함수 파일을 사용해서 작성되었습니다.topless는 생각지도 못하고 편리해서 바로 다른 OS에서도 동작하도록 퍼졌습니다.하지만 배포하는 단계에 이르러서야 문제를 알 수 있었습니다.셸스크립트를 2개의 파일로 나누어 배포하는 것이 공통인식으로 받아들여지기 어렵습니다.셸 스크립트라면 그 단체를 다운로드해서 사용할 수 없으면 의미가 없다고 할까, 사용하기 어렵다는 것입니다.이 문제에 대처하기 위해 shsubrmerge 명령이 작성되었습니다.예를 들어 목록 3.2를 인수로 지정하고 shsubrmerge 명령을 실행하면 다음과 같은 셸 스크립트가 표준출력으로 출력됩니다.리스트 3.1의 함수가 통합되어 있는 모습을 알 수 있습니다.리스트 5.1 shsubrmerge가 실행된 경우의 예시
# ! / bin / sh

# usage
# print usage
# usage
# usage _ msg = ′ usage message ′
# usage
usage ( )
{
echo ′ $ usage _ msg ′ 1 > & 2
}

usage _ msg = ′ usage :
command message
- h print help message ′

[ 0 = $ # ] && { usage ; exit ; }

echo ′$@′shsubrmerge 명령을 사용하면 배포용 셸 스크립트를 자동으로 생성할 수 있습니다.shubrmerge 커멘드의 처리내용 shsubrmerge 커멘드의 처리는 크게 3순서로 이루어집니다.공유 함수 파일에서 함수를 추출하다
셸 스크립트에서 사용되고 있는 함수를 조사하다
인크루드한 부분을 사용되는 함수로 치환하는 셸 스크립트에서는 해석 프로그램을 사용하고 있는 것이 아니기 때문에 복잡한 해석을 실시할 수 없습니다.shsubrmerge 명령에서는 공유 함수 파일이 리스트 3.1과 같이 작성되었다고 가정하고 처리를 하고 있습니다.shsubrmerge 명령어는 우선 공유 함수 파일을 한 줄씩 읽어 매칭에 따라 처리합니다.조심할 필요가 있는 것은, while로 한줄씩 읽을 때 IFS= 를 지정해 두는 것입니다.이렇게 하지 않으면 공백탭이 구분자로 해석이 되고 행의 내용이 변경될 수 있습니다.리스트 6.1 공유함수 파일을 가져오는 ′while IFS=read line′
cat ′ $ { 0 % / * } ′ / . shsubr |
while IFS = read line
do
잘라낸 함수는 일단 파일에 출력하고 있습니다.셸 스크립트에서 사용되는 함수는 grep에서 조사하고 있습니다.일치된 함수는 변수에 모습니다.리스트 6.2 셸 스크립트에서 사용되고 있는 함수를 조사한다.
commandlist = $ ( ls ′ $ tempdir ′ )
for command in $ commandlist
do
grep -- ′ $ command ′ ′ $1 ′ > / dev / null && {
[ - z ′ $ functions ′ ] &&
functions = ′ $ ( cat ′ $ tempdir / $ command ′ ) ′ ||
functions = ′ $ ( echo ′ $ functions ′ ; echo ; cat ′ $ tempdir / $ command ′ ) ′
}
done 마지막으로 Marge합니다.「.shsubr」를 읽고 있는 줄 번호를 알아보고, 거기까지를 head로 출력, 함수를 출력, 그 이후를 tail로 출력하고 있습니다.리스트 6.3 셸 스크립트와 함수의 Marge
includeline = $ ( cat - n ′ $1 ′ | grep ′ / * } ′ / . shsubr ′ | head - 1 | awk
′ { print $1 } ′ )

head - $ (( $ includeline - 1 )) ′ $1 ′
echo ′ $ functions ′
tail - $ (( $ ( wc - l ′ $1 ′ | awk ′{print $1}′) - $includeline) ′$1′ 쉘스크립트로 구현할 수 있는 내용은 기본적으로 명령어가 가능한 것, 그리고 명령어를 조합하여 할 수 있는 것입니다.다른 프로그래밍 언어와 같은 발상으로 작성하려고 해도 잘 되지 않습니다.시점을 명령어를 사용하는 곳에 두는 것이 중요합니다.정리 셸 스크립트를 효과적으로 활용하려면 자주 사용하는 처리를 공유함수로서 파일에 정리해 두면 좋을 것입니다.다만, 셸 스크립트는 그 파일 단체로 사용하는 관례가 강하기 때문에, 실행하기 위해서 복수의 파일이 있으면 다른 환경에 가지고 갔을 때에 사용하기 어려워집니다.본 글에서는 이를 방지하기 위해 공유함수 파일과 셸 스크립트를 통합하는 명령어 shsubrmerge를 소개했습니다.덧붙여 shsubrmerge 커맨드 자신은 FreeBSD로 작성되었습니다.다른 OS 에서는 동작 확인을 하고 있지 않습니다.게다가, 대상으로 하고 있는 공유 함수 파일도, 명령어와 같은 디렉토리에 있는 「.shsubr」파일로 고정되어 있습니다.shsubrmerge 명령어는 셸 스크립트에서 많은 작업을 하는 헤비유저에게는 편리한 명령어입니다.다운로드한 shsubrmerge 명령을 기반으로 자신의 환경에 맞게 커스터마이즈하십시오.수작업을 하고 있는 곳을 자동화하는 것이 셸 스크립트의 사용목적 중 하나입니다.짐작 가는 부분이 있다면, 셸 스크립트로 자동화를 해 봅시다.
반응형