2017년 7월 22일 토요일

고급 Bash 스크립팅 가이드: Bash를 이용한 쉘 스크립팅 완전 가이드

부록 G. 도스(DOS) 배치 파일을 쉘 스크립트로 변환

아주 많은 프로그래머들은 PC 위에서 도는 도스에서 스크립트를 배웠습니다. 기능이 조금 떨어지는 도스 배치 파일 언어로도 꽤 강력한 스크립트나 어플리케이션을 작성할 수도 있지만 그렇게 하려면 아주 해박한 지식을 사용해 해결책을 찾거나 꽁수를 부려야 합니다. 가끔은 오래된 도스용 배치 파일을 유닉스 쉘 스크립트로 변환해서 써야될 경우가 생기지만 이렇게 하는것이 그렇게 어렵지만은 않습니다. 왜냐하면 도스 배치 파일 연산자들이 기능이 동일한 쉘 스크립트 연산자의 서브셋에 불과하기 때문입니다.

표 G-1. 배치 파일 키워드/변수/연산자 와 그에 해당하는 쉘 동의어
배치 파일 연산자    쉘 스크립트 동의어    뜻
%    $    명령어줄 매개변수 접두사
/    -    명령어 옵션 플래그
\    /    디렉토리 패스 구분자
==    =    (같음) 문자열 비교 테스트
!==!    !=    (다름) 문자열 비교 테스트
|    |    파이프
@    set +v    현재 명령어를 에코하지 말 것
*    *    파일명 "와일드 카드"
>    >    파일 재지향(덮어 쓰기)
>>    >>    파일 재지향(덧붙여 쓰기)
<    <    표준입력 재지향
%VAR%    $VAR    환경 변수
REM    #    주석
NOT    !    뒤에 나오는 테스트 부정
NUL    /dev/null    명령어 출력을 없애기 위한 "블랙홀"
ECHO    echo    에코 (Bash 에는 옵션이 많이 있음)
ECHO.    echo    빈 줄 에코
ECHO OFF    set +v    다음에 나오는 명령어를 에코하지 말 것
FOR %%VAR IN (LIST) DO    for var in [list]; do    "for" 루프
:LABEL    없음 (필요치 않음)    라벨
GOTO    없음 (대신 함수를 씀)    스크립트의 다른 곳으로 건너 뜀
PAUSE    sleep    일정 간격을 두고 잠시 대기
CHOICE    case 나 select    메뉴 선택
IF    if    if-test
IF EXIST FILENAME    if [ -e filename ]    파일이 존재하는지 확인
IF !%N==!    if [ -z "$N" ]    변경가능한 매개변수인 "N"이 없다면
CALL    source 나 . (도트 연산자)    다른 스크립트를 "포함"
COMMAND /C    source 나 . (도트 연산자)    다른 스크립트를 "포함"(CALL과 동일)
SET    export    환경 변수를 세트
SHIFT    shift    명령어줄 변수 목록을 왼쪽으로 이동(shift)
SGN    -lt or -gt    (정수) 부호(sign)
ERRORLEVEL    $?    종료 상태
CON    stdin    "콘솔"(표준입력)
PRN    /dev/lp0    (일반적인) 프린터 디바이스
LP1    /dev/lp0    첫번째 프린터 디바이스
COM1    /dev/ttyS0    첫번째 시리얼 포트

배치 파일은 대개 도스 명령어를 갖고 있습니다. 도스용 배치 파일이 쉘 스크립트로 변환되기 위해서는 이 명령어들은 꼭 동일한 유닉스 명령어로 변환되어야 합니다.

표 G-2. 도스 명령어와 동일한 유닉스 명령어
도스 명령어    동일한 유닉스 명령어    효과
ASSIGN    ln    파일이나 디렉토리를 링크
ATTRIB    chmod    파일 퍼미션 변경
CD    cd    디렉토리 변경
CHDIR    cd    디렉토리 변경
CLS    clear    스크린 지우기
COMP    cmp or diff    파일 비교
COPY    cp    파일 복사
Ctl-C    Ctl-C    정지(시그널)
Ctl-Z    Ctl-D    EOF (end-of-file)
DEL    rm    파일 삭제
DELTREE    rm -rf    디렉토리의 하위 디렉토리까지 포함해서 삭제
DIR    ls -l    디렉토리 보이기
ERASE    rm    파일 삭제
EXIT    exit    현재 프로세스 종료
FC    comm, cmp    파일 비교
FIND    grep    파일안에서 문자열 찾기
MD    mkdir    디렉토리 생성
MKDIR    mkdir    디렉토리 생성
MORE    more    텍스트 파일 쪽단위(paging) 필터
MOVE    mv    이동
PATH    $PATH    실행파일들의 경로
REN    mv    이름 바꾸기(이동)
RENAME    mv    이름 바꾸기(이동)
RD    rmdir    디렉토리 삭제
RMDIR    rmdir    디렉토리 삭제
SORT    sort    파일 정렬
TIME    date    시스템 시간 보여주기
TYPE    cat    파일을 표준출력으로 출력
XCOPY    cp    (확장) 파일 복사

    참고: 사실 모든 유닉스, 쉘 연산자, 명령어들은 그들과 동일한 도스용보다 많은 옵션과 강력한 기능을 갖고 있습니다. 많은 배치 파일 스크립트들은 read의 불완전한 버전인 ask.com같은 외부 유틸리티에 의존합니다.

    도스는 파일명 와일드 카드 확장에 대해서 오직 *과 ? 문자만을 인식하는 제한되고 부족한 서브셋을 지원합니다.

도스 배치 파일을 쉘 스크립트로 변환하는 것은 일반적으로 매우 간단하고 가끔은 변환된 쉘 스크립트가 원래 도스 배치 파일보다 더 이해하기 쉬운 경우도 있습니다.

예 G-1. VIEWDATA.BAT: 도스용 배치 파일

REM VIEWDATA

REM PAUL SOMERSON의 "DOS POWERTOOLS"의 예제에서 영감을 받아 작성


@ECHO OFF

IF !%1==! GOTO VIEWDATA
REM  명령어줄 인자가 없다면...
FIND "%1" C:\BOZO\BOOKLIST.TXT
GOTO EXIT0
REM  문자열이 일치하는 줄을 출력후 종료.

:VIEWDATA
TYPE C:\BOZO\BOOKLIST.TXT | MORE
REM  한 번에 한 쪽씩 전체 파일을 보여줌.

:EXIT0

스크립트 변환을 하면 기능이 다소 개량됩니다.

예 G-2. viewdata.sh: VIEWDATA.BAT 의 스크립트 버전

#!/bin/bash
# VIEWDATA.BAT 를 쉘 스크립트로 변환.

DATAFILE=/home/bozo/datafiles/book-collection.data
ARGNO=1

# @ECHO OFF       여기서 이 명령어는 필요없습니다.

if [ $# -lt "$ARGNO" ]    # IF !%1==! GOTO VIEWDATA
then
  less $DATAFILE          # TYPE C:\MYDIR\BOOKLIST.TXT | MORE
else
  grep "$1" $DATAFILE     # FIND "%1" C:\MYDIR\BOOKLIST.TXT
fi 

exit 0                    # :EXIT0

# GOTO, 라벨, 속임수, 엉터리 구문등이 필요없어졌죠.
# 원래 배치 파일보다 더 짧고, 더 쉽고, 더 깔끔합니다.

Ted Davis 의 Shell Scripts on the PC 사이트에서는 구식 배치 파일 프로그래밍에 대한 포괄적인 튜토리얼을 소개하고 있습니다. 생각건대, 그의 독창적인 몇몇 테크닉들은 쉘 스크립트와 연관성이 있습니다.