newuids [-c N]이 프로그램의 기본 동작은 /etc/passwd 패스워드 파일 내에서 사용할 수 있는 첫 번째 사용되지 않은 UID를 출력하는 것이다. 만약 N 카운트를 가진 -c 옵션을 사용하게 되면 사용되지 않은 UID번호들을 N개 출력한다.
#! /bin/ksh # newuids --- print one or more unused uids # # usage: # newuids [-c N] # -c N print N unused uids다음에는 몇 개의 변수 할당내용과 프로그램이 종료될 때 임시 파일을 지우기 위한 트랩 명령이 오게된다.
PASSWD=${PASSWD:-/etc/passwd} TMPFILE=/tmp/uidlist$$ trap "rm -f $TMPFILE" EXIT HUP TERM # clean up on exit or signal그 다음에는 인자(argument)를 파싱(parsing)하게된다. 우리는 하나의 가능한 옵션을 처리하기 위해 내장된 getopts 명령을 사용한다. 단지 하나의 옵션일 경우에는 반드시 사용할 필요가 없는 기술이지만 시간이 흐르면서 더 많은 옵션이 추가될 경우 더 편리하게 사용될 수 있기 때문이다. 미리 계획해서 손해 보는 일은 없다.
count=1 # how many uids to print # parse arguments, let ksh issue diagnostics # and exit if need be while getopts "c#" opt do case $opt in c) count=$OPTARG ;; esac done유닉스 /etc/passwd 파일은 한 라인당 한 명의 사용자라는 시스템 사용자들을 나타낸다. 각 라인은 사용자 명, 암호화된 패스워드 필드, UID, 그룹 ID, 사용자의 완전한 이름(full name), 홈 디렉토리(그 사용자를 위한 $HOME 초기값), 마지막으로 로그인 과 같은 일곱 개의 필드로 구성되며 이 필드들은 콜론으로 구분된다. 예를 들면 아래와 같다.
arnold:xyzzy42:2076:10:Arnold D. Robbins:/home/arnold:/bin/ksh사용되지 않은 UID수를 발견하려면 우리는 패스워드 파일에서 사용하고 있는 UID번호들을 순차적으로 리스트하는 작업부터 해야 한다. UID번호 추출은 awk으로 할 수 있으며 그러한 리스트를 정렬하는 작업은 sort로 할 수 있다. 정렬된 리스트는 $TMPFILE이라는 파일명으로 저장된다.
awk -F: "{ print $3 }" $PASSWD | # generate list of uids sort -n -u > $TMPFILE # sort numerically, remove duplicates이제 정렬된 리스트를 인덱스된 배열 uid리스트로 읽을 수 있으며 변수 totalids 내의 총 요소의 수를 저장한다.
set -A uidlist $(< $TMPFILE) # save in indexed array totalids=${#uidlist[*]} # total number of uids이 시점에서 모든 셋업은 완료된다. 남아있는 모든 것은 비연속적인 한 쌍의 엔트리드를 발견하는 배열위의 루프이다. 하나가 발견되면 스크립트는 그 엔트리 안의 첫 번째 엔트리와 두 번째 값 사이에 모든 값들을 출력해준다. 변수 카운트는 각 회마다 감소하게 되어 결국 그 프로그램은 사용되지않은 UID의 요구한 수보다 더 많은 수는 확실히 출력하지 않을 것이라는 것을 알 수 있다.
# loop over ids, finding non-contiguous ones for ((i = 2; i <= totalids; i++)) do if (( uidlist[i-1] + 1 != uidlist[i] )) then for ((j = uidlist[i-1] + 1; j < uidlist[i]; j++)) do print $j if (( --count == 0 )) then break 2 fi done fi done이 루프를 주목해야 할 첫 번째 이유는 콘 셸(Korn Shell)의 ((...)) 구조로 만드는 것이 사용상에 있어 부담스럽다는 점이다. 특히 ((...)) 안의 변수들은 자신의 값을 얻기 위해 달러 표시를 할 필요가 없으며 하위스크립트를 위해서 숫자 표현들을 사용할 수 있다. (단지 ((...)) 안에 있는 것으로 제한되지는 않기 때문에 숫자 표현을 사용할 수 있음.) --count 표현은 그 값을 테스트하기 전에 count를 감소시킨다. 만약 count가 1에서 시작된다면 이는 0이 될 것이다. 더 높은 초기값도 그것이 0이 될 때까지 감소될 것이다.
참고 도서 Learning the Korn Shell, 2nd Edition |
#! /bin/ksh # newuids --- print one or more unused uids # # usage: # newuids [-c N] # -c N print N unused uids PASSWD=${PASSWD:-/etc/passwd} TMPFILE=/tmp/uidlist$$ trap "rm -f $TMPFILE" EXIT HUP TERM # clean up on exit or signal count=1 # how many uids to print # parse arguments, let ksh issue diagnostics # and exit if need be while getopts "c#" opt do case $opt in c) count=$OPTARG ;; esac done awk -F: "{ print $3 }" $PASSWD | # generate list of uids sort -n -u > $TMPFILE # sort numerically, remove duplicates set -A uidlist $(< $TMPFILE) # save in indexed array totalids=${#uidlist[*]} # total number of uids # loop over ids, finding non-contiguous ones for ((i = 2; i <= totalids; i++)) do if (( uidlist[i-1] + 1 != uidlist[i] )) then for ((j = uidlist[i-1] + 1; j < uidlist[i]; j++)) do print $j if (( --count == 0 )) then break 2 fi done fi done이 스크립트는 업데이트할 수 있다. 예를 들어 가장 작게 허용된 UID번호를 지정하기위해 한 옵션을 추가한다고 생각해보자. 이 스크립트는 UID 숫자들의 범위가 서로 다른 학과나 학교로 할당되도록 정책지워진 중앙 서버에서 유용하게 사용될 수 있다.
이전 글 : 이아스님이 제공하는 자바 헤드라인
최신 콘텐츠