어떤 사용자가 어떤 특정한 세션이나 얼마 이상의 세션동안 스크립트를 돌렸는지를 보고 싶다면 각 스크립트마다 다음 줄들을 넣어 주면 됩니다. 이렇게 하면 스크립트 이름과 실행 시간의 기록들을 한 파일에서 계속 추적할 수 있게 됩니다.
# 추적할 스크립트의 끝에 다음을 추가(>>)하세요. date>> $SAVE_FILE # 날짜와 시간. echo $0>> $SAVE_FILE # 스크립트 이름. echo>> $SAVE_FILE # 빈 줄 구분자. # 당연한 얘기지만, SAVE_FILE 은 ~/.scripts-run 같은 이름으로 # ~/.bashrc 에 환경 변수로 정의하고 export 시켜야 됩니다. |
>> 연산자는 파일의 끝에 줄들을 추가해 줍니다. 그럼 이미 존재하는 파일의 맨 앞에 추가(prepend)하려면 어떻게 할까요?
file=data.txt title="***데이타 텍스트 파일의 제목 줄입니다***" echo $title | cat - $file >$file.new # "cat -" 은 표준출력을 $file 과 연결시켜 줍니다. # $title 이 "맨 앞"에 추가된 새 파일이 만들어 집니다. |
당연한 이야기지만, sed 도 이렇게 할 수 있습니다.
쉘 스크립트는 Tcl이나 wish 스크립트, 심지어는 Makefile 에서 내장 명령어처럼 동작할 수 있습니다. C 프로그램에서 system() 함수를 써서 system("script_name");이라고 외부 쉘 명령어를 부르는 것처럼 부를 수도 있습니다.
여러분이 자주 쓰고 유용해 보이는 정의들이나 함수들은 하나로 모아서 한 파일에 둔 다음, 다른 스크립트에서 이 파일을 도트(dot, .) 명령어나 source 명령어로 "포함"(include)해서 쓰도록 하세요.
# SCRIPT LIBRARY # ------ ------- # 주의: # "#!" 를 쓰면 안 됨. # "실제 코드" 도 안 됨. # 유용한 변수 정의 ROOT_UID=0 # 루트는 $UID 0. E_NOTROOT=101 # 루트 사용자가 아닌 에러. MAXRETVAL=256 # 함수의 최대(양수) 리턴값. SUCCESS=0 FAILURE=-1 # 함수 Usage () # "사용법:" 메세지. { if [ -z "$1" ] # 넘어온 인자 없음. then msg=filename else msg=$@ fi echo "사용법: `basename $0` "$msg"" } Check_if_root () # 스크립트를 루트로 돌리는지 확인. { # "ex39.sh" 예제에서 발췌. if [ "$UID" -ne "$ROOT_UID" ] then echo "이 스크립트는 루트로 실행시켜야 됩니다." exit $E_NOTROOT fi } CreateTempfileName () # "유일한" 임시 파일을 생성. { # "ex51.sh" 예제에서 발췌. prefix=temp suffix=`eval date +%s` Tempfilename=$prefix.$suffix } isalpha2 () # "전체 문자열"이 알파벳으로만 되어 있는지 확인. { # "isalpha.sh" 에서 발췌. [ $# -eq 1 ] || return $FAILURE case $1 in *[!a-zA-Z]*|"") return $FAILURE;; *) return $SUCCESS;; esac # Thanks, S.C. } abs () # 절대값. { # 주의: 최대 리턴값 = 256. E_ARGERR=-999999 if [ -z "$1" ] # 인자가 필요함. then return $E_ARGERR # 명백한 에러값이 리턴. fi if [ "$1" -ge 0 ] # 음수가 아니면, then # absval=$1 # 그냥 그대로. else # 음수면, let "absval = (( 0 - $1 ))" # 부호를 변경. fi return $absval } |
스크립트를 좀 더 명확하고 읽기 쉽게 하기 위해서 특별한 용도의 주석을 쓰세요.
## 경고. rm -rf *.zzy ## "rm" 에 "-rf" 옵션을 주면 아주 위험하고 ##+ 특히나 와일드 카드와 같이 쓰면 더욱 위험합니다. #+ 연속되는 줄. # 이건 여러줄짜리 주석의 #+ 첫번째 줄이고, #+ 여긴 마지막 줄. #* 주의. #o 리스트 아이템. #> 다른 관점. while [ "$var1" != "end" ] #> while test "$var1" != "end" |
$? 종료 상태 변수를 쓰면 매개변수가 오직 숫자로만 이루어졌는지 확인할 수 있고 그렇다면 그 매개변수를 정수로 처리할 수 있습니다.
#!/bin/bash SUCCESS=0 E_BADINPUT=65 test "$1" -ne 0 -o "$1" -eq 0 2>/dev/null # 정수는 0 과 같거나 0 과 같지 않습니다. # 2>/dev/null 는 에러 메세지를 없애 줍니다. if [ $? -ne "$SUCCESS" ] then echo "사용법: `basename $0` integer-input" exit $E_BADINPUT fi let "sum = $1 + 25" # $1 이 정수가 아니라면 에러를 냅니다. echo "Sum = $sum" # 명령어줄 매개변수뿐만 아니라 어떤 변수라도 이런식으로 테스트 할 수 있습니다. exit 0 |
이중 중괄호를 쓰면 for 나 while 루프에서도 C 형태의 문법으로 변수를 세팅하거나 증가시킬수 있습니다. 예 10-11와 예 10-16를 참고하세요.
run-parts 명령어는 여러 명령어 스크립트를 차례대로 실행시킬 때 편한데 특히 cron 이나 at과 같이 쓰면 더욱 편합니다.
쉘 스크립트에서 X 윈도우 위젯을 부를 수 있다면 아주 멋지겠죠. Xscript나 Xmenu, widtools 같은 것들을 쓰면 X 윈도우 위젯을 부를 수 있습니다. 앞의 두 개는 더 이상 개발되지 않는 것 같은데, 다행스럽게도 widtools은 여기에서 구할 수 있습니다.
경고 |
widtools(widget tools)은 설치할 때 XForms 라이브러리가 있어야 됩니다. 게다가 일반적인 리눅스 시스템에서 빌드하기 전에 Makefile을 조심스럽게 편집해야 하는 번거로움도 있습니다. 끝으로, 제공되는 여섯개의 위젯중에 세개는 제대로 동작하지 않고 세그폴트를 일으킵니다. |
위젯을 이용해서 더 효과적인 스크립팅을 하려면 Tk나 wish(Tcl에서 나왔죠), PerlTk(펄용 Tk 확장), tksh(ksh용 Tk 확장), XForms4Perl(펄용 XForms 확장), Gtk-Perl(펄용 Gtk 확장), PyQt(파이썬용 Qt 확장)를 써 보세요.